summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
m---------src/3rdparty0
-rw-r--r--src/buildtools/config/common.pri (renamed from src/core/config/common.pri)27
-rw-r--r--src/buildtools/config/functions.pri (renamed from src/core/config/functions.pri)0
-rw-r--r--src/buildtools/config/linux.pri (renamed from src/core/config/linux.pri)1
-rw-r--r--src/buildtools/config/mac_osx.pri (renamed from src/core/config/mac_osx.pri)1
-rw-r--r--src/buildtools/config/support.pri133
-rw-r--r--src/buildtools/config/windows.pri (renamed from src/core/config/windows.pri)2
-rw-r--r--src/buildtools/configure.json769
-rw-r--r--src/buildtools/gn.pro4
-rw-r--r--src/buildtools/ninja.pro4
-rw-r--r--src/core/accessibility_tree_formatter_qt.cpp6
-rw-r--r--src/core/api/core_api.pro2
-rw-r--r--src/core/api/qtwebenginecoreglobal.cpp3
-rw-r--r--src/core/api/qwebenginefindtextresult.cpp116
-rw-r--r--src/core/api/qwebenginefindtextresult.h81
-rw-r--r--src/core/api/qwebengineurlrequestinfo.cpp62
-rw-r--r--src/core/api/qwebengineurlrequestinfo.h7
-rw-r--r--src/core/api/qwebengineurlrequestinfo_p.h3
-rw-r--r--src/core/api/qwebengineurlscheme.cpp10
-rw-r--r--src/core/api/qwebengineurlscheme.h1
-rw-r--r--src/core/authentication_dialog_controller.cpp15
-rw-r--r--src/core/authentication_dialog_controller_p.h10
-rw-r--r--src/core/browser_accessibility_qt.cpp8
-rw-r--r--src/core/browser_main_parts_qt.cpp64
-rw-r--r--src/core/browser_main_parts_qt.h14
-rw-r--r--src/core/browser_message_filter_qt.cpp2
-rw-r--r--src/core/browser_message_filter_qt.h2
-rw-r--r--src/core/browsing_data_remover_delegate_qt.cpp4
-rw-r--r--src/core/certificate_error_controller.cpp12
-rw-r--r--src/core/certificate_error_controller.h2
-rw-r--r--src/core/certificate_error_controller_p.h1
-rw-r--r--src/core/chromium_overrides.cpp17
-rw-r--r--src/core/common/qt_messages.h4
-rw-r--r--src/core/compositor/compositor_resource_fence.cpp8
-rw-r--r--src/core/compositor/compositor_resource_fence.h2
-rw-r--r--src/core/compositor/compositor_resource_tracker.h7
-rw-r--r--src/core/compositor/delegated_frame_node.cpp19
-rw-r--r--src/core/compositor/display_consumer.h62
-rw-r--r--src/core/compositor/display_frame_sink.cpp140
-rw-r--r--src/core/compositor/display_frame_sink.h77
-rw-r--r--src/core/compositor/display_gl_output_surface.cpp292
-rw-r--r--src/core/compositor/display_gl_output_surface.h148
-rw-r--r--src/core/compositor/display_gl_output_surface_qsg.cpp121
-rw-r--r--src/core/compositor/display_overrides.cpp80
-rw-r--r--src/core/compositor/display_producer.h69
-rw-r--r--src/core/compositor/display_software_output_surface.cpp173
-rw-r--r--src/core/compositor/display_software_output_surface.h62
-rw-r--r--src/core/configure.json580
-rw-r--r--src/core/content_browser_client_qt.cpp46
-rw-r--r--src/core/content_browser_client_qt.h19
-rw-r--r--src/core/content_main_delegate_qt.cpp5
-rw-r--r--src/core/core_chromium.pri16
-rw-r--r--src/core/core_common.pri3
-rw-r--r--src/core/core_module.pro2
-rw-r--r--src/core/delegated_frame_host_client_qt.cpp92
-rw-r--r--src/core/delegated_frame_host_client_qt.h73
-rw-r--r--src/core/devtools_frontend_qt.cpp18
-rw-r--r--src/core/download_manager_delegate_qt.cpp33
-rw-r--r--src/core/download_manager_delegate_qt.h1
-rw-r--r--src/core/extensions/component_extension_resource_manager_qt.cpp19
-rw-r--r--src/core/extensions/component_extension_resource_manager_qt.h8
-rw-r--r--src/core/extensions/extension_system_qt.h6
-rw-r--r--src/core/extensions/extension_web_contents_observer_qt.h2
-rw-r--r--src/core/extensions/extensions_browser_client_qt.cpp27
-rw-r--r--src/core/extensions/extensions_browser_client_qt.h4
-rw-r--r--src/core/favicon_manager.cpp14
-rw-r--r--src/core/favicon_manager.h3
-rw-r--r--src/core/find_text_helper.cpp171
-rw-r--r--src/core/find_text_helper.h102
-rw-r--r--src/core/gn_run.pro3
-rw-r--r--src/core/login_delegate_qt.cpp67
-rw-r--r--src/core/login_delegate_qt.h22
-rw-r--r--src/core/media_capture_devices_dispatcher.cpp51
-rw-r--r--src/core/net/client_cert_override.cpp20
-rw-r--r--src/core/net/client_cert_override.h4
-rw-r--r--src/core/net/cookie_monster_delegate_qt.cpp34
-rw-r--r--src/core/net/cookie_monster_delegate_qt.h7
-rw-r--r--src/core/net/network_delegate_qt.cpp17
-rw-r--r--src/core/net/url_request_custom_job.cpp26
-rw-r--r--src/core/net/url_request_custom_job.h3
-rw-r--r--src/core/net/url_request_custom_job_proxy.cpp3
-rw-r--r--src/core/net/webui_controller_factory_qt.cpp3
-rw-r--r--src/core/ozone/gl_context_qt.cpp11
-rw-r--r--src/core/ozone/gl_context_qt.h2
-rw-r--r--src/core/ozone/gl_ozone_glx_qt.cpp6
-rw-r--r--src/core/ozone/gl_ozone_glx_qt.h3
-rw-r--r--src/core/ozone/gl_surface_egl_qt.cpp7
-rw-r--r--src/core/ozone/gl_surface_glx_qt.cpp2
-rw-r--r--src/core/ozone/gl_surface_qt.cpp2
-rw-r--r--src/core/ozone/gl_surface_qt.h2
-rw-r--r--src/core/platform_notification_service_qt.cpp37
-rw-r--r--src/core/platform_notification_service_qt.h27
-rw-r--r--src/core/pref_service_adapter.cpp205
-rw-r--r--src/core/pref_service_adapter.h85
-rw-r--r--src/core/printing/print_view_manager_qt.cpp1
-rw-r--r--src/core/printing/print_view_manager_qt.h2
-rw-r--r--src/core/profile_adapter.cpp53
-rw-r--r--src/core/profile_adapter.h4
-rw-r--r--src/core/profile_adapter_client.h3
-rw-r--r--src/core/profile_io_data_qt.cpp68
-rw-r--r--src/core/profile_io_data_qt.h9
-rw-r--r--src/core/profile_qt.cpp95
-rw-r--r--src/core/profile_qt.h20
-rw-r--r--src/core/qtwebengine.gni1
-rw-r--r--src/core/qtwebengine_resources.gni2
-rw-r--r--src/core/qtwebengine_sources.gni7
-rw-r--r--src/core/render_widget_host_view_qt.cpp226
-rw-r--r--src/core/render_widget_host_view_qt.h45
-rw-r--r--src/core/render_widget_host_view_qt_delegate.h2
-rw-r--r--src/core/renderer/content_renderer_client_qt.cpp18
-rw-r--r--src/core/renderer/content_renderer_client_qt.h4
-rw-r--r--src/core/renderer/content_settings_observer_qt.cpp25
-rw-r--r--src/core/renderer/content_settings_observer_qt.h9
-rw-r--r--src/core/renderer/web_channel_ipc_transport.cpp4
-rw-r--r--src/core/renderer_host/resource_dispatcher_host_delegate_qt.cpp4
-rw-r--r--src/core/type_conversion.cpp19
-rw-r--r--src/core/type_conversion.h7
-rw-r--r--src/core/user_notification_controller.cpp8
-rw-r--r--src/core/web_contents_adapter.cpp427
-rw-r--r--src/core/web_contents_adapter.h38
-rw-r--r--src/core/web_contents_adapter_client.h21
-rw-r--r--src/core/web_contents_delegate_qt.cpp160
-rw-r--r--src/core/web_contents_delegate_qt.h42
-rw-r--r--src/core/web_contents_view_qt.h3
-rw-r--r--src/core/web_engine_context.cpp71
-rw-r--r--src/core/web_engine_settings.cpp6
-rw-r--r--src/core/web_engine_settings.h8
-rw-r--r--src/core/web_event_factory.cpp26
-rw-r--r--src/process/support_win.cpp3
-rw-r--r--src/src.pro59
-rw-r--r--src/webengine/api/qquickwebenginedialogrequests.cpp110
-rw-r--r--src/webengine/api/qquickwebenginedialogrequests_p.h33
-rw-r--r--src/webengine/api/qquickwebenginedownloaditem.cpp140
-rw-r--r--src/webengine/api/qquickwebenginedownloaditem_p.h19
-rw-r--r--src/webengine/api/qquickwebenginedownloaditem_p_p.h6
-rw-r--r--src/webengine/api/qquickwebenginenavigationrequest.cpp2
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp10
-rw-r--r--src/webengine/api/qquickwebengineview.cpp109
-rw-r--r--src/webengine/api/qquickwebengineview_p.h28
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h8
-rw-r--r--src/webengine/configure.json14
-rw-r--r--src/webengine/doc/src/webengineview_lgpl.qdoc108
-rw-r--r--src/webengine/plugin/plugin.cpp31
-rw-r--r--src/webengine/plugin/plugin.pro2
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.cpp6
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.h1
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp5
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.h1
-rw-r--r--src/webengine/ui_delegates_manager.cpp6
-rw-r--r--src/webenginewidgets/api/qwebenginecertificateerror.cpp109
-rw-r--r--src/webenginewidgets/api/qwebenginecertificateerror.h22
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem.cpp122
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem.h9
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem_p.h3
-rw-r--r--src/webenginewidgets/api/qwebenginehistory.cpp4
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp242
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h30
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h11
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp9
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp19
-rw-r--r--src/webenginewidgets/api/qwebengineview.h1
-rw-r--r--src/webenginewidgets/configure.json28
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc8
-rw-r--r--src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc2
-rw-r--r--src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc2
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp6
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h1
167 files changed, 5804 insertions, 1503 deletions
diff --git a/src/3rdparty b/src/3rdparty
-Subproject 0240cfc1a59deb5b612923d47ccef72f10504fe
+Subproject feccbb4ea7fa685dcd013f5a3f6c14ea768636c
diff --git a/src/core/config/common.pri b/src/buildtools/config/common.pri
index fce89f576..1a54f1559 100644
--- a/src/core/config/common.pri
+++ b/src/buildtools/config/common.pri
@@ -1,6 +1,7 @@
# Shared configuration for all our supported platforms
+include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri)
include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri)
-QT_FOR_CONFIG += webenginecore
+QT_FOR_CONFIG += buildtools-private webenginecore webenginecore-private
gn_args += \
use_qt=true \
@@ -12,6 +13,7 @@ gn_args += \
enable_nacl=false \
enable_remoting=false \
enable_reporting=false \
+ enable_resource_whitelist_generation=false \
enable_swiftshader=false \
enable_web_auth=false \
enable_web_speech=false \
@@ -27,10 +29,15 @@ gn_args += \
safe_browsing_mode=0 \
optimize_webui=false
-!win32: gn_args += \
- use_jumbo_build=true \
- jumbo_file_merge_limit=8 \
- jumbo_build_excluded="[\"browser\"]"
+greaterThan(QMAKE_JUMBO_MERGE_LIMIT,0) {
+ gn_args += \
+ use_jumbo_build=true \
+ jumbo_file_merge_limit=$$QMAKE_JUMBO_MERGE_LIMIT
+}
+
+!greaterThan(QMAKE_JUMBO_MERGE_LIMIT,8) {
+ gn_args += jumbo_build_excluded="[\"browser\"]"
+}
qtConfig(webengine-printing-and-pdf) {
gn_args += enable_basic_printing=true enable_print_preview=true
@@ -72,11 +79,11 @@ precompile_header {
gn_args += enable_precompiled_headers=false
}
-CONFIG(release, debug|release):!isDeveloperBuild() {
+CONFIG(release, debug|release):!qtConfig(webengine-developer-build) {
gn_args += is_official_build=true
} else {
gn_args += is_official_build=false
- !isDeveloperBuild(): gn_args += is_unsafe_developer_build=false
+ !qtConfig(webengine-developer-build): gn_args += is_unsafe_developer_build=false
}
CONFIG(release, debug|release) {
@@ -93,7 +100,7 @@ CONFIG(release, debug|release) {
CONFIG(debug, debug|release) {
gn_args += is_debug=true
gn_args += use_debug_fission=false
- # MSVC requires iterator debug to always match and Qt has leaves it default on.
+ # MSVC requires iterator debug to always match and Qt leaves it default on.
msvc: gn_args += enable_iterator_debugging=true
# We also can not have optimized V8 binaries for MSVC as iterator debugging
@@ -101,7 +108,7 @@ CONFIG(debug, debug|release) {
msvc|v8base_debug: gn_args += v8_optimized_debug=false
}
-!webcore_debug: gn_args += remove_webcore_debug_symbols=true
+!webcore_debug: gn_args += blink_symbol_level=0
!v8base_debug: gn_args += remove_v8base_debug_symbols=true
# Compiling with -Os makes a huge difference in binary size
@@ -115,7 +122,7 @@ optimize_size: gn_args += optimize_for_size=true
sanitize_undefined: gn_args += is_ubsan=true is_ubsan_vptr=true
}
-qtConfig(webengine-v8-snapshot) {
+qtConfig(webengine-v8-snapshot):qtConfig(webengine-v8-snapshot-support) {
gn_args += v8_use_snapshot=true
} else {
gn_args += v8_use_snapshot=false
diff --git a/src/core/config/functions.pri b/src/buildtools/config/functions.pri
index 8c11faa16..8c11faa16 100644
--- a/src/core/config/functions.pri
+++ b/src/buildtools/config/functions.pri
diff --git a/src/core/config/linux.pri b/src/buildtools/config/linux.pri
index 22cb5991f..493ea9766 100644
--- a/src/core/config/linux.pri
+++ b/src/buildtools/config/linux.pri
@@ -17,6 +17,7 @@ gn_args += \
use_sysroot=false \
enable_session_service=false \
is_cfi=false \
+ strip_absolute_paths_from_debug_symbols=false \
toolkit_views=false \
use_ozone=true \
ozone_auto_platforms=false \
diff --git a/src/core/config/mac_osx.pri b/src/buildtools/config/mac_osx.pri
index e49df90e7..3f2fe9c0a 100644
--- a/src/core/config/mac_osx.pri
+++ b/src/buildtools/config/mac_osx.pri
@@ -24,6 +24,7 @@ system("$${QMAKE_CLANG_PATH} --version")
gn_args += \
is_clang=true \
use_sysroot=false \
+ use_system_xcode=true \
clang_base_path=\"$${QMAKE_CLANG_DIR}\" \
clang_use_chrome_plugins=false \
mac_deployment_target=\"$${QMAKE_MACOSX_DEPLOYMENT_TARGET}\" \
diff --git a/src/buildtools/config/support.pri b/src/buildtools/config/support.pri
new file mode 100644
index 000000000..5bdd808d4
--- /dev/null
+++ b/src/buildtools/config/support.pri
@@ -0,0 +1,133 @@
+defineTest(qtwebengine_skipBuild) {
+ isEmpty(skipBuildReason): skipBuildReason = $$1
+ else: skipBuildReason = "$$skipBuildReason $${EOL}$$1"
+ export(skipBuildReason)
+}
+
+defineReplace(qtwebengine_checkError) {
+
+ static {
+ qtwebengine_skipBuild("Static builds of QtWebEngine are not supported.")
+ return(false)
+ }
+
+ !qtHaveModule(gui) {
+ qtwebengine_skipBuild("QtWebEngine requires QtGui.")
+ return(false)
+ }
+
+ !qtConfig(webengine-submodule) {
+ qtwebengine_skipBuild("QtWebEngine required submodule qtwebengine-chromium does not exist. Run 'git submodule update --init'.")
+ return(false)
+ }
+
+ !qtConfig(webengine-nowhitespace) {
+ qtwebengine_skipBuild("QtWebEngine cannot be built in a path that contains whitespace characters.")
+ return(false)
+ }
+
+ qtConfig(webengine-no-platform-support) {
+ !isEmpty(platformError) {
+ qtwebengine_skipBuild($$platformError)
+ return(false)
+ }
+ !isEmpty(QTWEBENGINE_OUT_ROOT) {
+ include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri)
+ QT_FOR_CONFIG += buildtools-private
+ qtwebengine_skipBuild($$PLATFORM_ERROR)
+ return(false)
+ }
+ qtwebengine_skipBuild("QtWebEngine will not be built. Platform unsupported.") # re-run of configure when topLevel build
+ return(false):
+ }
+
+ !qtConfig(webengine-arch-support) {
+ qtwebengine_skipBuild("QtWebEngine can only be built for x86, x86-64, ARM, Aarch64, and MIPSel architectures.")
+ return(false)
+ }
+
+ !qtConfig(webengine-gperf) {
+ qtwebengine_skipBuild("Tool gperf is required to build QtWebEngine.")
+ return(false)
+ }
+
+ !qtConfig(webengine-bison) {
+ qtwebengine_skipBuild("Tool bison is required to build QtWebEngine.")
+ return(false)
+ }
+
+ !qtConfig(webengine-flex) {
+ qtwebengine_skipBuild("Tool flex is required to build QtWebEngine.")
+ return(false)
+ }
+
+ !qtConfig(webengine-python2) {
+ qtwebengine_skipBuild("Python version 2 (2.7.5 or later) is required to build QtWebEngine.")
+ return(false)
+ }
+
+ linux:!qtwebengine_checkErrorForLinux():return(false)
+ win:!qtwebengine_checkErrorForWindows():return(false)
+
+ sanitizer: !qtConfig(webengine-sanitizer) {
+ qtwebengine_skipBuild("Chosen sanitizer configuration is not supported for QtWebEngine. Check config.log for details or use -feature-webengine-sanitizer to force build with the chosen sanitizer configuration.")
+ return(false);
+ }
+
+ return(true)
+}
+
+defineTest(qtwebengine_checkErrorForLinux) {
+
+ !qtConfig(pkg-config) {
+ qtwebengine_skipBuild("A pkg-config support is required to build QtWebEngine.")
+ return(false)
+ }
+
+ !qtConfig(webengine-host-pkg-config) {
+ qtwebengine_skipBuild("Host pkg-config is required to build QtWebEngine.")
+ return(false)
+ }
+
+ !qtConfig(webengine-system-glibc) {
+ qtwebengine_skipBuild("A suitable version >= 2.27 of libc required to build QtWebEngine could not be found.")
+ return(false)
+ }
+
+ !qtConfig(webengine-system-khr) {
+ qtwebengine_skipBuild("Khronos development headers required to build QtWebEngine are missing (see mesa/libegl1-mesa-dev)")
+ return(false)
+ }
+
+ for(package, $$list("nss dbus fontconfig")) {
+ !qtConfig(webengine-system-$$package) {
+ qtwebengine_skipBuild("A suitable version of $$package required to build QtWebEngine could not be found.")
+ return(false)
+ }
+ }
+
+ qtConfig(pkg-config):qtConfig(xcb):!qtConfig(webengine-ozone-x11) {
+ qtwebengine_skipBuild("Could not find all necessary libraries for qpa-xcb support in QtWebEngine.")
+ return(false)
+ }
+ return(true)
+}
+
+defineTest(qtwebengine_checkErrorForWindows) {
+ !qtConfig(webengine-win-compiler64) {
+ qtwebengine_skipBuild("64-bit cross-building or native toolchain required to build QtWebEngine could not be found.")
+ return(false)
+ }
+
+ !qtConfig(webengine-winversion) {
+ qtwebengine_skipBuild("QtWebEngine needs Visual Studio 2017 or higher.")
+ return(false)
+ }
+ return(true)
+}
+
+defineTest(qtwebengine_makeCheckError) {
+ include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri)
+ QT_FOR_CONFIG += buildtools-private gui-private
+ return($$qtwebengine_checkError())
+}
diff --git a/src/core/config/windows.pri b/src/buildtools/config/windows.pri
index 385faeed0..dfa40e9dc 100644
--- a/src/core/config/windows.pri
+++ b/src/buildtools/config/windows.pri
@@ -22,7 +22,7 @@ clang_cl {
gn_args += is_clang=false use_lld=false
}
-isDeveloperBuild() {
+qtConfig(webengine-developer-build) {
gn_args += \
is_win_fastlink=true
diff --git a/src/buildtools/configure.json b/src/buildtools/configure.json
new file mode 100644
index 000000000..535d8358b
--- /dev/null
+++ b/src/buildtools/configure.json
@@ -0,0 +1,769 @@
+{
+ "module": "buildtools",
+ "depends": [
+ "core-private",
+ "gui-private",
+ "printsupport"
+ ],
+ "commandline": {
+ "options": {
+ "build-qtwebengine-core": "boolean",
+ "webengine-jumbo-build": { "type": "optionalString", "name": "merge_limit"}
+ }
+ },
+ "libraries": {
+ "webengine-dbus": {
+ "label": "d-bus",
+ "sources": [
+ { "type": "pkgConfig", "args": "dbus-1" }
+ ]
+ },
+ "webengine-fontconfig": {
+ "label": "fontconfig",
+ "sources": [
+ { "type": "pkgConfig", "args": "fontconfig" }
+ ]
+ },
+ "webengine-libdrm": {
+ "label": "libdrm",
+ "sources": [
+ { "type": "pkgConfig", "args": "libdrm" }
+ ]
+ },
+ "webengine-xcomposite": {
+ "label": "xcomposite",
+ "sources": [
+ { "type": "pkgConfig", "args": "xcomposite" }
+ ]
+ },
+ "webengine-xcursor": {
+ "label": "xcursor",
+ "sources": [
+ { "type": "pkgConfig", "args": "xcursor" }
+ ]
+ },
+ "webengine-xi": {
+ "label": "xi",
+ "sources": [
+ { "type": "pkgConfig", "args": "xi" }
+ ]
+ },
+ "webengine-xtst": {
+ "label": "xtst",
+ "sources": [
+ { "type": "pkgConfig", "args": "xtst" }
+ ]
+ },
+ "webengine-nss": {
+ "label": "nss >= 3.26",
+ "sources": [
+ { "type": "pkgConfig", "args": "nss >= 3.26" }
+ ]
+ },
+ "webengine-x11" : {
+ "label" : "x11",
+ "sources": [
+ { "type": "pkgConfig", "args": "x11" }
+ ]
+ },
+ "webengine-glib": {
+ "label": "glib-2.0 >= 2.32.0",
+ "sources": [
+ { "type": "pkgConfig", "args": "glib-2.0 >= 2.32.0" }
+ ]
+ },
+ "webengine-harfbuzz": {
+ "label": "harfbuzz >= 2.2.0",
+ "sources": [
+ { "type": "pkgConfig", "args": "harfbuzz >= 2.2.0" }
+ ]
+ },
+ "webengine-jpeglib": {
+ "label": "compatible jpeglib",
+ "type": "compile",
+ "test": {
+ "head": [
+ "#include <cstdio>",
+ "#include <cstring>",
+ "extern \"C\" {",
+ " #include <jpeglib.h>",
+ "}"
+ ],
+ "main": [
+ "JDIMENSION dummy;",
+ "jpeg_crop_scanline(nullptr, &dummy, &dummy);",
+ "jpeg_skip_scanlines(nullptr, dummy);"
+ ]
+ },
+ "sources": [
+ { "type": "pkgConfig", "args": "libjpeg" },
+ "-ljpeg"
+ ]
+ },
+ "webengine-jsoncpp": {
+ "label": "jsoncpp",
+ "sources": [
+ { "type": "pkgConfig", "args": "jsoncpp" }
+ ]
+ },
+ "webengine-libevent": {
+ "label": "libevent",
+ "sources": [
+ { "type": "pkgConfig", "args": "libevent" }
+ ]
+ },
+ "webengine-minizip": {
+ "label": "minizip",
+ "sources": [
+ { "type": "pkgConfig", "args": "minizip" }
+ ]
+ },
+ "webengine-png": {
+ "label": "libpng >= 1.6.0",
+ "sources": [
+ { "type": "pkgConfig", "args": "libpng >= 1.6.0" }
+ ]
+ },
+ "webengine-protobuf": {
+ "label": "protobuf",
+ "sources": [
+ { "type": "pkgConfig", "args": "protobuf" }
+ ]
+ },
+ "webengine-zlib": {
+ "label": "zlib",
+ "sources": [
+ { "type": "pkgConfig", "args": "zlib" }
+ ]
+ },
+ "webengine-re2": {
+ "label": "re2",
+ "test" : {
+ "main": [
+ "std::string s;",
+ "RE2 re2(s);"
+ ]
+ },
+ "headers": "re2/re2.h",
+ "sources": [
+ { "type": "pkgConfig", "args": "re2" }
+ ]
+ },
+ "webengine-icu": {
+ "label": "icu >= 63",
+ "sources": [
+ { "type": "pkgConfig", "args": "icu-uc >= 63 icu-i18n >= 63" }
+ ]
+ },
+ "webengine-webp": {
+ "label": "libwebp, libwebpmux and libwebpdemux",
+ "sources": [
+ { "type": "pkgConfig", "args": "libwebp libwebpmux libwebpdemux" }
+ ]
+ },
+ "webengine-lcms2": {
+ "label": "lcms2",
+ "sources": [
+ { "type": "pkgConfig", "args": "lcms2" }
+ ]
+ },
+ "webengine-freetype": {
+ "label": "freetype >= 2.4.2",
+ "test": {
+ "head": [
+ "#include <ft2build.h>",
+ "#include FT_FREETYPE_H",
+ "#if ((FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) < 20402)",
+ "# error This version of freetype is too old.",
+ "#endif"
+ ],
+ "main": [
+ "FT_Face ft_face = 0;",
+ "FT_Reference_Face(ft_face);"
+ ]
+ },
+ "sources": [
+ { "type": "pkgConfig", "args": "freetype2" }
+ ]
+ },
+ "webengine-libxml2": {
+ "label": "compatible libxml2 and libxslt",
+ "type": "compile",
+ "test": {
+ "tail": [
+ "#if !defined(LIBXML_ICU_ENABLED)",
+ "#error libxml icu not enabled",
+ "#endif"
+ ]
+ },
+ "headers": "libxml/xmlversion.h",
+ "sources": [
+ { "type": "pkgConfig", "args": "libxml-2.0 libxslt" }
+ ]
+ },
+ "webengine-libdrm": {
+ "label": "libdrm",
+ "sources": [
+ { "type": "pkgConfig", "args": "libdrm" }
+ ]
+ },
+ "webengine-xcomposite": {
+ "label": "xcomposite",
+ "sources": [
+ { "type": "pkgConfig", "args": "xcomposite" }
+ ]
+ },
+ "webengine-xcursor": {
+ "label": "xcursor",
+ "sources": [
+ { "type": "pkgConfig", "args": "xcursor" }
+ ]
+ },
+ "webengine-xi": {
+ "label": "xi",
+ "sources": [
+ { "type": "pkgConfig", "args": "xi" }
+ ]
+ },
+ "webengine-xtst": {
+ "label": "xtst",
+ "sources": [
+ { "type": "pkgConfig", "args": "xtst" }
+ ]
+ },
+ "webengine-ffmpeg": {
+ "label": "libavcodec libavformat libavutil",
+ "sources": [
+ { "type": "pkgConfig", "args": "libavcodec libavformat libavutil" }
+ ]
+ },
+ "webengine-opus": {
+ "label": "opus",
+ "sources": [
+ { "type": "pkgConfig", "args": "opus" }
+ ]
+ },
+ "webengine-snappy": {
+ "label": "snappy",
+ "test": {
+ "main": [
+ "snappy::Source *src = 0;",
+ "snappy::Sink *sink = 0;"
+ ]
+ },
+ "headers": "snappy.h",
+ "sources": [
+ "-lsnappy"
+ ]
+ },
+ "webengine-libvpx": {
+ "label": "libvpx",
+ "test": {
+ "main": [
+ "vpx_codec_cx_pkt pkt;",
+ "pkt.data.frame.width[0] = 0u;",
+ "pkt.data.frame.height[0] = 0u;"
+ ]
+ },
+ "headers": "vpx/vpx_encoder.h",
+ "sources": [
+ { "type": "pkgConfig", "args": "vpx" },
+ "-lvpx"
+ ]
+ }
+ },
+
+ "testDir": "config.tests",
+ "tests" : {
+ "webengine-bison": {
+ "label": "bison",
+ "type": "detectBison"
+ },
+ "webengine-flex": {
+ "label": "flex",
+ "type": "detectFlex"
+ },
+ "webengine-gn": {
+ "label": "system gn",
+ "type": "detectGn"
+ },
+ "webengine-glibc": {
+ "label": "glibc > 2.16",
+ "type": "compile",
+ "test": {
+ "include": "features.h",
+ "tail": [
+ "#if __GLIBC__ < 2 || __GLIBC_MINOR__ < 17",
+ "#error glibc versions below 2.17 are not supported",
+ "#endif"
+ ]
+ }
+ },
+ "webengine-gperf": {
+ "label": "gperf",
+ "type": "detectGperf"
+ },
+ "webengine-khr": {
+ "label": "khr",
+ "type": "compile",
+ "test": {
+ "include": "KHR/khrplatform.h",
+ "qmake" : [
+ "!isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL",
+ "!isEmpty(QMAKE_INCDIR_OPENGL): INCLUDEPATH += $$QMAKE_INCDIR_OPENGL"
+ ]
+ }
+ },
+ "webengine-ninja": {
+ "label": "system ninja",
+ "type": "detectNinja"
+ },
+ "webengine-python2": {
+ "label": "python2",
+ "type": "detectPython2",
+ "log": "location"
+ },
+ "webengine-winversion": {
+ "label": "winversion",
+ "type": "compile",
+ "test": {
+ "head" : [
+ "#if !defined(__clang__) && _MSC_FULL_VER < 191426428",
+ "#error unsupported Visual Studio version",
+ "#endif"
+ ]
+ }
+ },
+ "webengine-host-pkg-config": {
+ "label": "host pkg-config",
+ "type": "detectHostPkgConfig",
+ "log": "path"
+ },
+ "webengine-jumbo-build": {
+ "label": "jumbo build merge limit",
+ "type": "detectJumboBuild",
+ "log": "merge_limit"
+ },
+ "webengine-protoc": {
+ "label": "protoc",
+ "type": "detectProtoc"
+ },
+ "webengine-win-compiler64": {
+ "label": "64bit compiler",
+ "type": "isWindowsHostCompiler64"
+ },
+ "webengine-platform-support": {
+ "label": "platform supported",
+ "type": "detectPlatform",
+ "log": "platformSupport"
+ },
+ "webengine-arch-support": {
+ "label": "architecture supported",
+ "type": "detectArch"
+ },
+ "webengine-submodule" : {
+ "label": "submodule initialized",
+ "type": "detectSubmodule"
+ },
+ "webengine-nowhitespace" : {
+ "label": "build path without whitespace",
+ "type": "detectNoWhitespace"
+ }
+ },
+ "features": {
+ "webengine-core-support": {
+ "label": "Support Qt WebEngine Core",
+ "condition": "module.gui
+ && features.webengine-python2
+ && features.webengine-gperf
+ && features.webengine-bison
+ && features.webengine-flex
+ && features.webengine-submodule
+ && features.webengine-nowhitespace
+ && features.webengine-arch-support
+ && !features.webengine-no-platform-support
+ && !config.static
+ && (!config.linux || features.pkg-config)
+ && (!features.xcb || features.webengine-ozone-x11)
+ && (!config.win32 || features.webengine-winversion)",
+ "output": [ "privateFeature" ]
+ },
+ "build-qtwebengine-core": {
+ "label": "Build Qt WebEngine Core",
+ "purpose": "Provides WebEngine Core support.",
+ "output": [ "privateFeature" ]
+ },
+ "build-qtpdf": {
+ "label": "Support Qt PDF rendering module",
+ "purpose": "Enables building the Qt PDF rendering module.",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-developer-build": {
+ "label": "Developer build",
+ "purpose": "Enables the developer build configuration.",
+ "autoDetect": "features.private_tests",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-python2": {
+ "label": "python2",
+ "condition": "tests.webengine-python2",
+ "output": [
+ "privateFeature",
+ { "type": "varAssign", "name": "QMAKE_PYTHON2", "value": "tests.webengine-python2.location" }
+ ]
+ },
+ "webengine-gperf": {
+ "label": "gperf",
+ "condition": "tests.webengine-gperf",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-bison": {
+ "label": "bison",
+ "condition": "tests.webengine-bison",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-flex": {
+ "label": "flex",
+ "condition": "tests.webengine-flex",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-ninja": {
+ "label": "Use System Ninja",
+ "condition": "tests.webengine-ninja",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-fontconfig": {
+ "label": "fontconfig",
+ "condition": "libs.webengine-fontconfig",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-dbus": {
+ "label": "dbus",
+ "condition": "libs.webengine-dbus",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-libdrm": {
+ "label": "libdrm",
+ "condition": "libs.webengine-libdrm",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-xcomposite": {
+ "label": "xcomposite",
+ "condition": "libs.webengine-xcomposite",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-xcursor": {
+ "label": "xcursor",
+ "condition": "libs.webengine-xcursor",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-xi": {
+ "label": "xi",
+ "condition": "libs.webengine-xi",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-xtst": {
+ "label": "xtst",
+ "condition": "libs.webengine-xtst",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-gn": {
+ "label": "Use System Gn",
+ "autoDetect": "false",
+ "condition": "tests.webengine-gn",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-khr" : {
+ "label": "khr",
+ "condition": "config.unix && tests.webengine-khr",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-nss": {
+ "label": "nss",
+ "condition": "config.unix && !config.darwin && libs.webengine-nss",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-glibc": {
+ "label": "glibc",
+ "condition": "config.linux && tests.webengine-glibc",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-x11" : {
+ "label": "x11",
+ "condition": "config.unix && libs.webengine-x11",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-host-pkg-config": {
+ "label": "host-pkg-config",
+ "condition": "config.unix && tests.webengine-host-pkg-config",
+ "output": [
+ "privateFeature",
+ { "type": "varAssign", "name": "QMAKE_PKG_CONFIG_HOST", "value": "tests.webengine-host-pkg-config.path" }
+ ]
+ },
+ "webengine-ozone-x11" : {
+ "label": "Support qpa-xcb",
+ "condition": "config.unix
+ && features.xcb
+ && features.webengine-system-x11
+ && features.webengine-system-libdrm
+ && features.webengine-system-xcomposite
+ && features.webengine-system-xcursor
+ && features.webengine-system-xi
+ && features.webengine-system-xtst",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-jumbo-build": {
+ "label": "jumbo build merge batch",
+ "condition": "tests.webengine-jumbo-build",
+ "output": [
+ "privateFeature",
+ { "type": "varAssign", "name": "QMAKE_JUMBO_MERGE_LIMIT", "value": "tests.webengine-jumbo-build.merge_limit" }
+ ]
+ },
+ "webengine-system-libdrm": {
+ "label": "libdrm",
+ "condition": "libs.webengine-libdrm",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-xcomposite": {
+ "label": "xcomposite",
+ "condition": "libs.webengine-xcomposite",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-xcursor": {
+ "label": "xcursor",
+ "condition": "libs.webengine-xcursor",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-xi": {
+ "label": "xi",
+ "condition": "libs.webengine-xi",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-xtst": {
+ "label": "xtst",
+ "condition": "libs.webengine-xtst",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-harfbuzz": {
+ "label": "harfbuzz",
+ "condition": "config.unix && features.system-harfbuzz && libs.webengine-harfbuzz",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-glib" : {
+ "label": "glib",
+ "condition": "config.unix && libs.webengine-glib",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-minizip" : {
+ "label": "minizip",
+ "condition": "config.unix && libs.webengine-minizip",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-zlib" : {
+ "label": "zlib",
+ "condition": "config.unix && features.system-zlib && libs.webengine-zlib",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-libevent" : {
+ "label": "libevent",
+ "condition": "config.unix && libs.webengine-libevent",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-jsoncpp" : {
+ "label": "jsoncpp",
+ "condition": "config.unix && libs.webengine-jsoncpp",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-protobuf" : {
+ "label": "protobuf",
+ "condition": "config.unix && libs.webengine-protobuf && tests.webengine-protoc",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-png" : {
+ "label": "png",
+ "condition": "config.unix && features.system-png && libs.webengine-png",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-jpeg" : {
+ "label": "JPEG",
+ "condition": "config.unix && features.system-jpeg && libs.webengine-jpeglib",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-re2": {
+ "label": "re2",
+ "condition": "config.unix && libs.webengine-re2",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-icu": {
+ "label": "icu",
+ "autoDetect": "false",
+ "condition": "libs.webengine-icu",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-libwebp": {
+ "label": "libwebp, libwebpmux and libwebpdemux",
+ "condition": "config.unix && libs.webengine-webp",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-opus": {
+ "label": "opus",
+ "condition": "config.unix && libs.webengine-opus",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-ffmpeg": {
+ "label": "ffmpeg",
+ "autoDetect": "false",
+ "condition": "libs.webengine-ffmpeg && features.webengine-system-opus && features.webengine-system-libwebp",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-libxml2": {
+ "label": "libxml2 and libxslt",
+ "condition": "config.unix && libs.webengine-libxml2",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-lcms2" : {
+ "label": "lcms2",
+ "condition": "config.unix && libs.webengine-lcms2",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-freetype" : {
+ "label": "freetype",
+ "condition": "config.unix && features.system-freetype && libs.webengine-freetype",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-libvpx" : {
+ "label": "libvpx",
+ "condition": "config.unix && libs.webengine-libvpx",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-system-snappy" : {
+ "label": "snappy",
+ "condition": "config.unix && libs.webengine-snappy",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-winversion" : {
+ "label": "winversion",
+ "condition": "config.win32 && tests.webengine-winversion",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-win-compiler64": {
+ "label": "64bit compiler",
+ "condition": "config.win32 && tests.webengine-win-compiler64",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-submodule": {
+ "label": "submodule",
+ "condition": "tests.webengine-submodule",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-nowhitespace": {
+ "label": "nowhitespace",
+ "condition" : "tests.webengine-nowhitespace",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-arch-support": {
+ "label": "architecture",
+ "condition" : "tests.webengine-arch-support",
+ "output": [ "privateFeature" ]
+ },
+ "webengine-no-platform-support": {
+ "label": "platform",
+ "condition" : "!tests.webengine-platform-support",
+ "output": [
+ "privateFeature",
+ { "type": "varAssign", "name": "PLATFORM_ERROR", "value": "tests.webengine-platform-support.platformSupport" }
+ ]
+ }
+ },
+ "report": [
+ {
+ "type": "skipBuildWarning",
+ "condition": "!features.webengine-core-support && (features.build-qtwebengine-core || features.build-qtpdf)",
+ "message": "qtwebengine_confCheckError"
+ },
+ {
+ "type": "note",
+ "condition": "features.webengine-core-support && !features.build-qtwebengine-core",
+ "message": "QtWebEngine build is disabled by user."
+ },
+ {
+ "type": "note",
+ "condition": "features.webengine-core-support && !features.build-qtpdf",
+ "message": "QtPdf build is disabled by user."
+ },
+ {
+ "type": "warning",
+ "condition": "!features.webengine-core-support && features.build-qtwebengine-core",
+ "message": "QtWebEngine will not be built."
+ },
+ {
+ "type": "warning",
+ "condition": "!features.webengine-core-support && features.build-qtpdf",
+ "message": "QtPdf will not be built."
+ }
+ ],
+ "summary": [
+ {
+ "section": "Qt WebEngine Build Tools",
+ "entries": [
+ "webengine-system-ninja",
+ "webengine-system-gn",
+ {
+ "message": "Jumbo Build Merge Limit",
+ "type": "jumboBuild"
+ },
+ "webengine-developer-build",
+ {
+ "section": "QtWebEngine required system libraries",
+ "condition": "config.unix && !config.macos",
+ "entries": [
+ "webengine-system-fontconfig",
+ "webengine-system-dbus",
+ "webengine-system-nss",
+ "webengine-system-khr",
+ "webengine-system-glibc"
+ ]
+ },
+ {
+ "section": "QtWebEngine required system libraries for qpa-xcb",
+ "condition": "config.unix && !config.macos && features.xcb",
+ "entries": [
+ "webengine-system-x11",
+ "webengine-system-libdrm",
+ "webengine-system-xcomposite",
+ "webengine-system-xcursor",
+ "webengine-system-xi",
+ "webengine-system-xtst"
+ ]
+ },
+ {
+ "section": "Optional system libraries used",
+ "condition": "config.unix",
+ "entries": [
+ "webengine-system-re2",
+ "webengine-system-icu",
+ "webengine-system-libwebp",
+ "webengine-system-opus",
+ "webengine-system-ffmpeg",
+ "webengine-system-libvpx",
+ "webengine-system-snappy",
+ "webengine-system-glib",
+ "webengine-system-zlib",
+ "webengine-system-minizip",
+ "webengine-system-libevent",
+ "webengine-system-jsoncpp",
+ "webengine-system-protobuf",
+ "webengine-system-libxml2",
+ "webengine-system-lcms2",
+ "webengine-system-png",
+ "webengine-system-jpeg",
+ "webengine-system-harfbuzz",
+ "webengine-system-freetype"
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/buildtools/gn.pro b/src/buildtools/gn.pro
index b6bf9cfc4..033202e6e 100644
--- a/src/buildtools/gn.pro
+++ b/src/buildtools/gn.pro
@@ -3,8 +3,8 @@ option(host_build)
!debug_and_release: CONFIG += release
-include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri)
-QT_FOR_CONFIG += webenginecore-private
+include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri)
+QT_FOR_CONFIG += buildtools-private
build_pass|!debug_and_release {
!qtConfig(webengine-system-gn): CONFIG(release, debug|release) {
diff --git a/src/buildtools/ninja.pro b/src/buildtools/ninja.pro
index 6382d6cfb..66a6d5aa6 100644
--- a/src/buildtools/ninja.pro
+++ b/src/buildtools/ninja.pro
@@ -2,8 +2,8 @@ TEMPLATE = aux
!debug_and_release: CONFIG += release
-include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri)
-QT_FOR_CONFIG += webenginecore-private
+include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri)
+QT_FOR_CONFIG += buildtools-private
build_pass|!debug_and_release {
!qtConfig(webengine-system-ninja): CONFIG(release, debug|release) {
diff --git a/src/core/accessibility_tree_formatter_qt.cpp b/src/core/accessibility_tree_formatter_qt.cpp
index 706857207..3520087ae 100644
--- a/src/core/accessibility_tree_formatter_qt.cpp
+++ b/src/core/accessibility_tree_formatter_qt.cpp
@@ -63,6 +63,7 @@ private:
const std::string GetAllowEmptyString() override;
const std::string GetAllowString() override;
const std::string GetDenyString() override;
+ const std::string GetDenyNodeString() override;
void AddProperties(const BrowserAccessibility &node, base::DictionaryValue* dict) override;
base::string16 ProcessTreeForOutput(const base::DictionaryValue &node, base::DictionaryValue * = nullptr) override;
};
@@ -198,6 +199,11 @@ const std::string AccessibilityTreeFormatterQt::GetDenyString()
return "@QT-DENY:";
}
+const std::string AccessibilityTreeFormatterQt::GetDenyNodeString()
+{
+ return "@QT-DENY-NODE:";
+}
+
#endif // QT_NO_ACCESSIBILITY
// static
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro
index 326d4481f..5e8b8387e 100644
--- a/src/core/api/core_api.pro
+++ b/src/core/api/core_api.pro
@@ -37,6 +37,7 @@ HEADERS = \
qtwebenginecoreglobal_p.h \
qwebenginecookiestore.h \
qwebenginecookiestore_p.h \
+ qwebenginefindtextresult.h \
qwebenginehttprequest.h \
qwebenginemessagepumpscheduler_p.h \
qwebenginenotification.h \
@@ -53,6 +54,7 @@ SOURCES = \
qtwebenginecoreglobal.cpp \
qwebengineclientcertificatestore.cpp \
qwebenginecookiestore.cpp \
+ qwebenginefindtextresult.cpp \
qwebenginehttprequest.cpp \
qwebenginemessagepumpscheduler.cpp \
qwebenginenotification.cpp \
diff --git a/src/core/api/qtwebenginecoreglobal.cpp b/src/core/api/qtwebenginecoreglobal.cpp
index 25d0bd3be..0fddacb15 100644
--- a/src/core/api/qtwebenginecoreglobal.cpp
+++ b/src/core/api/qtwebenginecoreglobal.cpp
@@ -125,6 +125,9 @@ Q_WEBENGINECORE_PRIVATE_EXPORT void initialize()
return;
shareContext = new QOpenGLContext;
+ QSurfaceFormat format = QSurfaceFormat::defaultFormat();
+ format.setOption(QSurfaceFormat::ResetNotification);
+ shareContext->setFormat(format);
shareContext->create();
qAddPostRoutine(deleteShareContext);
qt_gl_set_global_share_context(shareContext);
diff --git a/src/core/api/qwebenginefindtextresult.cpp b/src/core/api/qwebenginefindtextresult.cpp
new file mode 100644
index 000000000..ce1be359e
--- /dev/null
+++ b/src/core/api/qwebenginefindtextresult.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwebenginefindtextresult.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWebEngineFindTextResultPrivate : public QSharedData {
+public:
+ int numberOfMatches = 0;
+ int activeMatchOrdinal = 0;
+};
+
+/*!
+ \class QWebEngineFindTextResult
+ \brief The QWebEngineFindTextResult class encapsulates the result of a string search on a page.
+ \since 5.14
+
+ \inmodule QtWebEngineCore
+
+ Results are passed to the user in the
+ \l QWebEnginePage::findTextFinished() and
+ \l{WebEngineView::findTextFinished()}{WebEngineView.findTextFinished()} signals.
+*/
+
+/*! \internal
+*/
+QWebEngineFindTextResult::QWebEngineFindTextResult()
+ : d(new QWebEngineFindTextResultPrivate)
+{}
+
+/*! \internal
+*/
+QWebEngineFindTextResult::QWebEngineFindTextResult(int numberOfMatches, int activeMatchOrdinal)
+ : d(new QWebEngineFindTextResultPrivate)
+{
+ d->numberOfMatches = numberOfMatches;
+ d->activeMatchOrdinal = activeMatchOrdinal;
+}
+
+/*! \internal
+*/
+QWebEngineFindTextResult::QWebEngineFindTextResult(const QWebEngineFindTextResult &other)
+ : d(other.d)
+{}
+
+/*! \internal
+*/
+QWebEngineFindTextResult &QWebEngineFindTextResult::operator=(const QWebEngineFindTextResult &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*! \internal
+*/
+QWebEngineFindTextResult::~QWebEngineFindTextResult()
+{}
+
+/*!
+ \property QWebEngineFindTextResult::numberOfMatches
+ \brief The number of matches found.
+*/
+int QWebEngineFindTextResult::numberOfMatches() const
+{
+ return d->numberOfMatches;
+}
+
+/*!
+ \property QWebEngineFindTextResult::activeMatchOrdinal
+ \brief The index of the currently highlighted match.
+*/
+int QWebEngineFindTextResult::activeMatchOrdinal() const
+{
+ return d->activeMatchOrdinal;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qwebenginefindtextresult.cpp"
diff --git a/src/core/api/qwebenginefindtextresult.h b/src/core/api/qwebenginefindtextresult.h
new file mode 100644
index 000000000..073a8135f
--- /dev/null
+++ b/src/core/api/qwebenginefindtextresult.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENGINEFINDTEXTRESULT_H
+#define QWEBENGINEFINDTEXTRESULT_H
+
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+#include <QtCore/QObject>
+#include <QtCore/QSharedData>
+
+namespace QtWebEngineCore {
+class FindTextHelper;
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWebEngineFindTextResultPrivate;
+
+class Q_WEBENGINECORE_EXPORT QWebEngineFindTextResult {
+ Q_GADGET
+ Q_PROPERTY(int numberOfMatches READ numberOfMatches CONSTANT FINAL)
+ Q_PROPERTY(int activeMatchOrdinal READ activeMatchOrdinal CONSTANT FINAL)
+
+public:
+ int numberOfMatches() const;
+ int activeMatchOrdinal() const;
+
+ QWebEngineFindTextResult();
+ QWebEngineFindTextResult(const QWebEngineFindTextResult &other);
+ QWebEngineFindTextResult &operator=(const QWebEngineFindTextResult &other);
+ ~QWebEngineFindTextResult();
+
+private:
+ QWebEngineFindTextResult(int numberOfMatches, int activeMatchOrdinal);
+
+ QSharedDataPointer<QWebEngineFindTextResultPrivate> d;
+
+ friend class QtWebEngineCore::FindTextHelper;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QWebEngineFindTextResult)
+
+#endif // QWEBENGINEFINDTEXTRESULT_H
diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp
index 3cbb4da17..2aa43a318 100644
--- a/src/core/api/qwebengineurlrequestinfo.cpp
+++ b/src/core/api/qwebengineurlrequestinfo.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -46,25 +46,26 @@
QT_BEGIN_NAMESPACE
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeMainFrame, content::RESOURCE_TYPE_MAIN_FRAME)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeSubFrame, content::RESOURCE_TYPE_SUB_FRAME)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeStylesheet, content::RESOURCE_TYPE_STYLESHEET)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeScript, content::RESOURCE_TYPE_SCRIPT)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeImage, content::RESOURCE_TYPE_IMAGE)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeFontResource, content::RESOURCE_TYPE_FONT_RESOURCE)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeSubResource, content::RESOURCE_TYPE_SUB_RESOURCE)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeObject, content::RESOURCE_TYPE_OBJECT)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeMedia, content::RESOURCE_TYPE_MEDIA)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeWorker, content::RESOURCE_TYPE_WORKER)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeSharedWorker, content::RESOURCE_TYPE_SHARED_WORKER)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePrefetch, content::RESOURCE_TYPE_PREFETCH)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeFavicon, content::RESOURCE_TYPE_FAVICON)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeXhr, content::RESOURCE_TYPE_XHR)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePing, content::RESOURCE_TYPE_PING)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeServiceWorker, content::RESOURCE_TYPE_SERVICE_WORKER)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeCspReport, content::RESOURCE_TYPE_CSP_REPORT)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePluginResource, content::RESOURCE_TYPE_PLUGIN_RESOURCE)
-ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeLast, content::RESOURCE_TYPE_LAST_TYPE)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeMainFrame, content::ResourceType::kMainFrame)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeSubFrame, content::ResourceType::kSubFrame)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeStylesheet, content::ResourceType::kStylesheet)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeScript, content::ResourceType::kScript)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeImage, content::ResourceType::kImage)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeFontResource, content::ResourceType::kFontResource)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeSubResource, content::ResourceType::kSubResource)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeObject, content::ResourceType::kObject)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeMedia, content::ResourceType::kMedia)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeWorker, content::ResourceType::kWorker)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeSharedWorker, content::ResourceType::kSharedWorker)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePrefetch, content::ResourceType::kPrefetch)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeFavicon, content::ResourceType::kFavicon)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeXhr, content::ResourceType::kXhr)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePing, content::ResourceType::kPing)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeServiceWorker, content::ResourceType::kServiceWorker)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeCspReport, content::ResourceType::kCspReport)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePluginResource, content::ResourceType::kPluginResource)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeNavigationPreload, content::ResourceType::kNavigationPreload)
+ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeLast, content::ResourceType::kMaxValue)
ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::LinkNavigation, QWebEngineUrlRequestInfo::NavigationTypeLink)
ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::TypedNavigation, QWebEngineUrlRequestInfo::NavigationTypeTyped)
@@ -74,6 +75,7 @@ ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::BackForwardNavigat
QWebEngineUrlRequestInfo::NavigationTypeBackForward)
ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::ReloadNavigation, QWebEngineUrlRequestInfo::NavigationTypeReload)
ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::OtherNavigation, QWebEngineUrlRequestInfo::NavigationTypeOther)
+ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::RedirectNavigation, QWebEngineUrlRequestInfo::NavigationTypeRedirect)
/*!
\class QWebEngineUrlRequestInfo
@@ -128,12 +130,13 @@ ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::OtherNavigation, Q
QWebEngineUrlRequestInfoPrivate::QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRequestInfo::ResourceType resource,
QWebEngineUrlRequestInfo::NavigationType navigation,
- const QUrl &u, const QUrl &fpu, const QByteArray &m)
+ const QUrl &u, const QUrl &fpu, const QUrl &i, const QByteArray &m)
: resourceType(resource)
, navigationType(navigation)
, shouldBlockRequest(false)
, url(u)
, firstPartyUrl(fpu)
+ , initiator(i)
, method(m)
, changed(false)
{}
@@ -182,7 +185,9 @@ QWebEngineUrlRequestInfo::QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfoPriva
\value ResourceTypeCspReport A report of Content Security Policy (CSP)
violations. CSP reports are in JSON format and they are delivered by
HTTP POST requests to specified servers. (Added in Qt 5.7)
- \value ResourceTypePluginResource A resource requested by a plugin. (Added in Qt 5.7)
+ \value ResourceTypePluginResource A resource requested by a plugin. (Added in Qt 5.7)
+ \value ResourceTypeNavigationPreload A service worker navigation preload
+ request. (Added in Qt 5.14)
\value ResourceTypeUnknown Unknown request type.
\note For forward compatibility all values not matched should be treated as unknown,
@@ -210,6 +215,7 @@ QWebEngineUrlRequestInfo::ResourceType QWebEngineUrlRequestInfo::resourceType()
\value NavigationTypeFormSubmitted Navigation submits a form.
\value NavigationTypeBackForward Navigation initiated by a history action.
\value NavigationTypeReload Navigation initiated by refreshing the page.
+ \value NavigationTypeRedirect Navigation triggered automatically by page content or remote server.
\value NavigationTypeOther None of the above.
*/
@@ -244,6 +250,18 @@ QUrl QWebEngineUrlRequestInfo::firstPartyUrl() const
}
/*!
+ Returns the origin URL of the document that initiated
+ the navigation of a frame to another frame.
+
+ \since 5.14
+ */
+
+QUrl QWebEngineUrlRequestInfo::initiator() const
+{
+ return d_ptr->initiator;
+}
+
+/*!
Returns the HTTP method of the request (for example, GET or POST).
*/
diff --git a/src/core/api/qwebengineurlrequestinfo.h b/src/core/api/qwebengineurlrequestinfo.h
index cf5a4801d..c2c924b05 100644
--- a/src/core/api/qwebengineurlrequestinfo.h
+++ b/src/core/api/qwebengineurlrequestinfo.h
@@ -76,8 +76,9 @@ public:
ResourceTypeServiceWorker, // the main resource of a service worker.
ResourceTypeCspReport, // Content Security Policy (CSP) violation report
ResourceTypePluginResource, // A resource requested by a plugin
+ ResourceTypeNavigationPreload, // A service worker navigation preload request.
#ifndef Q_QDOC
- ResourceTypeLast,
+ ResourceTypeLast = ResourceTypeNavigationPreload,
#endif
ResourceTypeUnknown = 255
};
@@ -88,7 +89,8 @@ public:
NavigationTypeFormSubmitted,
NavigationTypeBackForward,
NavigationTypeReload,
- NavigationTypeOther
+ NavigationTypeOther,
+ NavigationTypeRedirect,
};
ResourceType resourceType() const;
@@ -96,6 +98,7 @@ public:
QUrl requestUrl() const;
QUrl firstPartyUrl() const;
+ QUrl initiator() const;
QByteArray requestMethod() const;
bool changed() const;
diff --git a/src/core/api/qwebengineurlrequestinfo_p.h b/src/core/api/qwebengineurlrequestinfo_p.h
index 9d795b2b5..35b5610be 100644
--- a/src/core/api/qwebengineurlrequestinfo_p.h
+++ b/src/core/api/qwebengineurlrequestinfo_p.h
@@ -70,7 +70,7 @@ class QWebEngineUrlRequestInfoPrivate {
public:
QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRequestInfo::ResourceType resource,
QWebEngineUrlRequestInfo::NavigationType navigation, const QUrl &u, const QUrl &fpu,
- const QByteArray &m);
+ const QUrl &i, const QByteArray &m);
QWebEngineUrlRequestInfo::ResourceType resourceType;
QWebEngineUrlRequestInfo::NavigationType navigationType;
@@ -78,6 +78,7 @@ public:
QUrl url;
QUrl firstPartyUrl;
+ QUrl initiator;
const QByteArray method;
bool changed;
QHash<QByteArray, QByteArray> extraHeaders;
diff --git a/src/core/api/qwebengineurlscheme.cpp b/src/core/api/qwebengineurlscheme.cpp
index f4efad717..f73992c6b 100644
--- a/src/core/api/qwebengineurlscheme.cpp
+++ b/src/core/api/qwebengineurlscheme.cpp
@@ -59,6 +59,7 @@ ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::NoAccessAllowed, url::CustomScheme::NoAc
ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::ServiceWorkersAllowed, url::CustomScheme::ServiceWorkersAllowed)
ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::ViewSourceAllowed, url::CustomScheme::ViewSourceAllowed)
ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::ContentSecurityPolicyIgnored, url::CustomScheme::ContentSecurityPolicyIgnored)
+ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::CorsEnabled, url::CustomScheme::CorsEnabled)
static bool g_schemesLocked = false;
@@ -190,6 +191,13 @@ public:
\value ContentSecurityPolicyIgnored
Indicates that accesses to this scheme should bypass all
Content-Security-Policy checks.
+
+ \value CorsEnabled
+ Enables cross-origin resource sharing (CORS) for this scheme. This flag is
+ required in order to, for example, use the scheme with the \l
+ {https://fetch.spec.whatwg.org/}{Fetch API}, or to deliver CSS fonts to a
+ different origin. The appropriate CORS headers are generated automatically by
+ the QWebEngineUrlRequestJob class. (Added in Qt 5.14)
*/
QWebEngineUrlScheme::QWebEngineUrlScheme(QWebEngineUrlSchemePrivate *d) : d(d) {}
@@ -374,7 +382,7 @@ void QWebEngineUrlScheme::registerScheme(const QWebEngineUrlScheme &scheme)
return;
}
- if (url::IsStandard(scheme.d->name.data(), url::Component(0, scheme.d->name.size()))) {
+ if (url::IsStandard(scheme.d->name.data(), url::Component(0, static_cast<int>(scheme.d->name.size())))) {
qWarning() << "QWebEngineUrlScheme::registerScheme: Scheme" << scheme.name() << "is a standard scheme";
return;
}
diff --git a/src/core/api/qwebengineurlscheme.h b/src/core/api/qwebengineurlscheme.h
index 095b47320..ecac44184 100644
--- a/src/core/api/qwebengineurlscheme.h
+++ b/src/core/api/qwebengineurlscheme.h
@@ -76,6 +76,7 @@ public:
ServiceWorkersAllowed = 0x10,
ViewSourceAllowed = 0x20,
ContentSecurityPolicyIgnored = 0x40,
+ CorsEnabled = 0x80,
};
Q_DECLARE_FLAGS(Flags, Flag)
Q_FLAG(Flags)
diff --git a/src/core/authentication_dialog_controller.cpp b/src/core/authentication_dialog_controller.cpp
index 1133b0bc1..23dd62979 100644
--- a/src/core/authentication_dialog_controller.cpp
+++ b/src/core/authentication_dialog_controller.cpp
@@ -46,7 +46,7 @@
namespace QtWebEngineCore {
-AuthenticationDialogControllerPrivate::AuthenticationDialogControllerPrivate(LoginDelegateQt *loginDelegate)
+AuthenticationDialogControllerPrivate::AuthenticationDialogControllerPrivate(base::WeakPtr<LoginDelegateQt> loginDelegate)
: loginDelegate(loginDelegate)
{
}
@@ -54,9 +54,10 @@ AuthenticationDialogControllerPrivate::AuthenticationDialogControllerPrivate(Log
void AuthenticationDialogControllerPrivate::dialogFinished(bool accepted, const QString &user, const QString &password)
{
base::PostTaskWithTraits(
- FROM_HERE, {content::BrowserThread::IO},
+ FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&LoginDelegateQt::sendAuthToRequester,
- loginDelegate, accepted, user, password));
+ loginDelegate,
+ accepted, user, password));
}
AuthenticationDialogController::AuthenticationDialogController(AuthenticationDialogControllerPrivate *dd)
@@ -71,22 +72,22 @@ AuthenticationDialogController::~AuthenticationDialogController()
QUrl AuthenticationDialogController::url() const
{
- return d->loginDelegate->url();
+ return d->url;
}
QString AuthenticationDialogController::realm() const
{
- return d->loginDelegate->realm();
+ return d->realm;
}
QString AuthenticationDialogController::host() const
{
- return d->loginDelegate->host();
+ return d->host;
}
bool AuthenticationDialogController::isProxy() const
{
- return d->loginDelegate->isProxy();
+ return d->isProxy;
}
void AuthenticationDialogController::accept(const QString &user, const QString &password)
diff --git a/src/core/authentication_dialog_controller_p.h b/src/core/authentication_dialog_controller_p.h
index 16069b9b1..1abff576d 100644
--- a/src/core/authentication_dialog_controller_p.h
+++ b/src/core/authentication_dialog_controller_p.h
@@ -40,7 +40,7 @@
#ifndef AUTHENTICATION_DIALOG_CONTROLLER_P_H
#define AUTHENTICATION_DIALOG_CONTROLLER_P_H
-#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
#include "login_delegate_qt.h"
@@ -49,10 +49,14 @@ namespace QtWebEngineCore {
class AuthenticationDialogControllerPrivate {
public:
- AuthenticationDialogControllerPrivate(LoginDelegateQt *loginDelegate);
+ AuthenticationDialogControllerPrivate(base::WeakPtr<LoginDelegateQt> loginDelegate);
void dialogFinished(bool accepted, const QString &user = QString(), const QString &password = QString());
- scoped_refptr<LoginDelegateQt> loginDelegate;
+ base::WeakPtr<LoginDelegateQt> loginDelegate;
+ QUrl url;
+ QString host;
+ QString realm;
+ bool isProxy;
};
} // namespace QtWebEngineCore
diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp
index 75527ea95..f7e9c1c4f 100644
--- a/src/core/browser_accessibility_qt.cpp
+++ b/src/core/browser_accessibility_qt.cpp
@@ -386,6 +386,8 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::ListItem;
case ax::mojom::Role::kListItem:
return QAccessible::ListItem;
+ case ax::mojom::Role::kListGrid:
+ return QAccessible::List;
case ax::mojom::Role::kListMarker:
return QAccessible::StaticText;
case ax::mojom::Role::kLog:
@@ -727,7 +729,11 @@ void BrowserAccessibilityQt::scrollToSubstring(int startIndex, int endIndex)
{
int count = characterCount();
if (startIndex < endIndex && endIndex < count)
- manager()->ScrollToMakeVisible(*this, GetPageBoundsForRange(startIndex, endIndex - startIndex));
+ manager()->ScrollToMakeVisible(*this,
+ GetRootFrameRangeBoundsRect(
+ startIndex,
+ endIndex - startIndex,
+ ui::AXClippingBehavior::kUnclipped));
}
QVariant BrowserAccessibilityQt::currentValue() const
diff --git a/src/core/browser_main_parts_qt.cpp b/src/core/browser_main_parts_qt.cpp
index dacaf177f..d42a931d0 100644
--- a/src/core/browser_main_parts_qt.cpp
+++ b/src/core/browser_main_parts_qt.cpp
@@ -42,9 +42,11 @@
#include "api/qwebenginemessagepumpscheduler_p.h"
#include "base/message_loop/message_loop.h"
-#include "base/message_loop/message_loop_impl.h"
#include "base/message_loop/message_loop_current.h"
+#include "base/message_loop/message_pump_for_ui.h"
#include "base/process/process.h"
+#include "base/task/sequence_manager/sequence_manager_impl.h"
+#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
#include "base/threading/thread_restrictions.h"
#include "content/public/browser/browser_main_parts.h"
#include "content/public/browser/browser_thread.h"
@@ -58,7 +60,6 @@
#include "extensions/extension_system_factory_qt.h"
#include "common/extensions/extensions_client_qt.h"
#endif //BUILDFLAG(ENABLE_EXTENSIONS)
-#include "services/resource_coordinator/public/cpp/process_resource_coordinator.h"
#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/service.h"
@@ -75,6 +76,7 @@
#endif
#if defined(OS_MACOSX)
+#include "base/message_loop/message_pump_mac.h"
#include "ui/base/idle/idle.h"
#endif
@@ -114,12 +116,7 @@ public:
: m_scheduler([this]() { handleScheduledWork(); })
{}
- void setDelegate(Delegate *delegate)
- {
- m_delegate = delegate;
- }
-
- void Run(Delegate *delegate) override
+ void Run(Delegate *) override
{
// This is used only when MessagePumpForUIQt is used outside of the GUI thread.
NOTIMPLEMENTED();
@@ -134,15 +131,26 @@ public:
void ScheduleWork() override
{
// NOTE: This method may called from any thread at any time.
+ ensureDelegate();
m_scheduler.scheduleWork();
}
void ScheduleDelayedWork(const base::TimeTicks &delayed_work_time) override
{
+ // NOTE: This method may called from any thread at any time.
+ ensureDelegate();
m_scheduler.scheduleDelayedWork(GetTimeIntervalMilliseconds(delayed_work_time));
}
private:
+ void ensureDelegate()
+ {
+ if (!m_delegate) {
+ auto seqMan = base::MessageLoopCurrent::GetCurrentSequenceManagerImpl();
+ m_delegate = static_cast<base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl *>(
+ seqMan->controller_.get());
+ }
+ }
// Both Qt and Chromium keep track of the current GL context by using
// thread-local variables, and naturally they are completely unaware of each
// other. As a result, when a QOpenGLContext is made current, the previous
@@ -190,8 +198,6 @@ private:
void handleScheduledWork()
{
- Q_ASSERT(m_delegate);
-
ScopedGLContextChecker glContextChecker;
bool more_work_is_plausible = m_delegate->DoWork();
@@ -213,29 +219,19 @@ private:
QWebEngineMessagePumpScheduler m_scheduler;
};
-// Needed to access protected constructor from MessageLoop.
-class MessageLoopForUIQt : public base::MessageLoop {
-public:
- MessageLoopForUIQt() : MessageLoop(TYPE_UI, base::BindOnce(&messagePumpFactory))
- {
- BindToCurrentThread();
-
- auto pump = static_cast<MessagePumpForUIQt *>(pump_);
- auto backend = static_cast<base::MessageLoopImpl *>(backend_.get());
- pump->setDelegate(backend);
- }
-private:
- static std::unique_ptr<base::MessagePump> messagePumpFactory()
- {
- return base::WrapUnique(new MessagePumpForUIQt);
+std::unique_ptr<base::MessagePump> messagePumpFactory()
+{
+ static bool madePrimaryPump = false;
+ if (!madePrimaryPump) {
+ madePrimaryPump = true;
+ return std::make_unique<MessagePumpForUIQt>();
}
-};
-
-BrowserMainPartsQt::BrowserMainPartsQt() : content::BrowserMainParts()
-{ }
-
-BrowserMainPartsQt::~BrowserMainPartsQt() = default;
-
+#if defined(OS_MACOSX)
+ return base::MessagePumpMac::Create();
+#else
+ return std::make_unique<base::MessagePumpForUI>();
+#endif
+}
int BrowserMainPartsQt::PreEarlyInitialization()
{
@@ -247,8 +243,6 @@ int BrowserMainPartsQt::PreEarlyInitialization()
void BrowserMainPartsQt::PreMainMessageLoopStart()
{
- // Overrides message loop creation in BrowserMainLoop::MainMessageLoopStart().
- m_mainMessageLoop.reset(new MessageLoopForUIQt);
}
void BrowserMainPartsQt::PreMainMessageLoopRun()
@@ -288,8 +282,6 @@ void BrowserMainPartsQt::ServiceManagerConnectionStarted(content::ServiceManager
{
ServiceQt::GetInstance()->InitConnector();
connection->GetConnector()->WarmService(service_manager::ServiceFilter::ByName("qtwebengine"));
- m_processResourceCoordinator = std::make_unique<resource_coordinator::ProcessResourceCoordinator>(connection->GetConnector());
- m_processResourceCoordinator->OnProcessLaunched(base::Process::Current());
}
} // namespace QtWebEngineCore
diff --git a/src/core/browser_main_parts_qt.h b/src/core/browser_main_parts_qt.h
index 4eb10e379..8c6d8340e 100644
--- a/src/core/browser_main_parts_qt.h
+++ b/src/core/browser_main_parts_qt.h
@@ -43,24 +43,22 @@
#include "content/public/browser/browser_main_parts.h"
namespace base {
-class MessageLoop;
+class MessagePump;
}
namespace content {
class ServiceManagerConnection;
}
-namespace resource_coordinator {
-class ProcessResourceCoordinator;
-}
-
namespace QtWebEngineCore {
+std::unique_ptr<base::MessagePump> messagePumpFactory();
+
class BrowserMainPartsQt : public content::BrowserMainParts
{
public:
- BrowserMainPartsQt();
- ~BrowserMainPartsQt();
+ BrowserMainPartsQt() = default;
+ ~BrowserMainPartsQt() override = default;
int PreEarlyInitialization() override;
void PreMainMessageLoopStart() override;
@@ -71,8 +69,6 @@ public:
private:
DISALLOW_COPY_AND_ASSIGN(BrowserMainPartsQt);
- std::unique_ptr<resource_coordinator::ProcessResourceCoordinator> m_processResourceCoordinator;
- std::unique_ptr<base::MessageLoop> m_mainMessageLoop;
};
} // namespace QtWebEngineCore
diff --git a/src/core/browser_message_filter_qt.cpp b/src/core/browser_message_filter_qt.cpp
index 034447512..c8fc88017 100644
--- a/src/core/browser_message_filter_qt.cpp
+++ b/src/core/browser_message_filter_qt.cpp
@@ -79,8 +79,6 @@ bool BrowserMessageFilterQt::OnMessageReceived(const IPC::Message& message)
void BrowserMessageFilterQt::OnAllowDatabase(int /*render_frame_id*/,
const GURL &origin_url,
const GURL &top_origin_url,
- const base::string16 &/*name*/,
- const base::string16 &/*display_name*/,
bool* allowed)
{
NetworkDelegateQt *networkDelegate = static_cast<NetworkDelegateQt *>(m_profile->GetRequestContext()->GetURLRequestContext()->network_delegate());
diff --git a/src/core/browser_message_filter_qt.h b/src/core/browser_message_filter_qt.h
index d121aa65d..3963fb9d5 100644
--- a/src/core/browser_message_filter_qt.h
+++ b/src/core/browser_message_filter_qt.h
@@ -60,8 +60,6 @@ private:
void OnAllowDatabase(int render_frame_id,
const GURL &origin_url,
const GURL &top_origin_url,
- const base::string16& name,
- const base::string16& display_name,
bool *allowed);
void OnAllowDOMStorage(int render_frame_id,
diff --git a/src/core/browsing_data_remover_delegate_qt.cpp b/src/core/browsing_data_remover_delegate_qt.cpp
index 78e6893ea..005a9820d 100644
--- a/src/core/browsing_data_remover_delegate_qt.cpp
+++ b/src/core/browsing_data_remover_delegate_qt.cpp
@@ -49,7 +49,7 @@
namespace QtWebEngineCore {
bool DoesOriginMatchEmbedderMask(int origin_type_mask,
- const GURL &origin,
+ const url::Origin &origin,
storage::SpecialStoragePolicy *policy) {
Q_UNUSED(origin_type_mask);
Q_UNUSED(origin);
@@ -58,7 +58,7 @@ bool DoesOriginMatchEmbedderMask(int origin_type_mask,
}
content::BrowsingDataRemoverDelegate::EmbedderOriginTypeMatcher BrowsingDataRemoverDelegateQt::GetOriginTypeMatcher() const {
- return base::Bind(&DoesOriginMatchEmbedderMask);
+ return base::BindRepeating(&DoesOriginMatchEmbedderMask);
}
bool BrowsingDataRemoverDelegateQt::MayRemoveDownloadHistory() const {
diff --git a/src/core/certificate_error_controller.cpp b/src/core/certificate_error_controller.cpp
index 3309db8f1..89c2980e3 100644
--- a/src/core/certificate_error_controller.cpp
+++ b/src/core/certificate_error_controller.cpp
@@ -90,9 +90,10 @@ CertificateErrorControllerPrivate::CertificateErrorControllerPrivate(int cert_er
, strictEnforcement(strict_enforcement)
, callback(cb)
{
- if (ssl_info.cert.get()) {
- validStart = toQt(ssl_info.cert->valid_start());
- validExpiry = toQt(ssl_info.cert->valid_expiry());
+ if (auto cert = ssl_info.cert.get()) {
+ validStart = toQt(cert->valid_start());
+ validExpiry = toQt(cert->valid_expiry());
+ chain = toCertificateChain(cert);
}
}
@@ -186,4 +187,9 @@ QString CertificateErrorController::errorString() const
return getQStringForMessageId(IDS_CERT_ERROR_UNKNOWN_ERROR_DESCRIPTION);
}
+QList<QSslCertificate> CertificateErrorController::chain() const
+{
+ return d->chain;
+}
+
QT_END_NAMESPACE
diff --git a/src/core/certificate_error_controller.h b/src/core/certificate_error_controller.h
index 5bea61c9b..7f5300dc8 100644
--- a/src/core/certificate_error_controller.h
+++ b/src/core/certificate_error_controller.h
@@ -55,6 +55,7 @@
#include <QtCore/QDateTime>
#include <QtCore/QUrl>
+#include <QtNetwork/QSslCertificate>
QT_BEGIN_NAMESPACE
@@ -95,6 +96,7 @@ public:
QString errorString() const;
QDateTime validStart() const;
QDateTime validExpiry() const;
+ QList<QSslCertificate> chain() const;
void accept(bool);
diff --git a/src/core/certificate_error_controller_p.h b/src/core/certificate_error_controller_p.h
index 3b4d0f3bf..d51a559d0 100644
--- a/src/core/certificate_error_controller_p.h
+++ b/src/core/certificate_error_controller_p.h
@@ -71,6 +71,7 @@ public:
bool fatalError;
bool strictEnforcement;
const base::Callback<void(content::CertificateRequestResultType)> callback;
+ QList<QSslCertificate> chain;
};
QT_END_NAMESPACE
diff --git a/src/core/chromium_overrides.cpp b/src/core/chromium_overrides.cpp
index c44d75a42..b226c34ea 100644
--- a/src/core/chromium_overrides.cpp
+++ b/src/core/chromium_overrides.cpp
@@ -42,7 +42,6 @@
#include "web_contents_view_qt.h"
#include "base/values.h"
-#include "content/browser/renderer_host/pepper/pepper_truetype_font_list.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/font_list.h"
@@ -120,22 +119,6 @@ std::unique_ptr<base::ListValue> GetFontList_SlowBlocking()
return std::move(font_list);
}
-#if QT_CONFIG(webengine_pepper_plugins)
-// content/browser/renderer_host/pepper/pepper_truetype_font_list.h
-void GetFontFamilies_SlowBlocking(std::vector<std::string> *font_families)
-{
- QFontDatabase database;
- for (auto family : database.families()){
- font_families->push_back(family.toStdString());
- }
-}
-
-void GetFontsInFamily_SlowBlocking(const std::string &, std::vector<ppapi::proxy::SerializedTrueTypeFontDesc> *)
-{
- QT_NOT_USED
-}
-#endif // QT_CONFIG(webengine_pepper_plugins)
-
} // namespace content
namespace aura {
diff --git a/src/core/common/qt_messages.h b/src/core/common/qt_messages.h
index 9add826ae..b99204b74 100644
--- a/src/core/common/qt_messages.h
+++ b/src/core/common/qt_messages.h
@@ -76,12 +76,10 @@ IPC_MESSAGE_ROUTED0(RenderViewObserverHostQt_DidFirstVisuallyNonEmptyLayout)
// Sent by the renderer process to check whether access to web databases is
// granted by content settings.
-IPC_SYNC_MESSAGE_CONTROL5_1(QtWebEngineHostMsg_AllowDatabase,
+IPC_SYNC_MESSAGE_CONTROL3_1(QtWebEngineHostMsg_AllowDatabase,
int /* render_frame_id */,
GURL /* origin_url */,
GURL /* top origin url */,
- base::string16 /* database name */,
- base::string16 /* database display name */,
bool /* allowed */)
// Sent by the renderer process to check whether access to DOM Storage is
diff --git a/src/core/compositor/compositor_resource_fence.cpp b/src/core/compositor/compositor_resource_fence.cpp
index 7fc5fbfb2..4179395d6 100644
--- a/src/core/compositor/compositor_resource_fence.cpp
+++ b/src/core/compositor/compositor_resource_fence.cpp
@@ -146,12 +146,12 @@ void CompositorResourceFence::release()
}
// static
-scoped_refptr<CompositorResourceFence> CompositorResourceFence::create()
+scoped_refptr<CompositorResourceFence> CompositorResourceFence::create(std::unique_ptr<gl::GLFence> glFence)
{
- if (gl::GLContext::GetCurrent() && gl::GLFence::IsSupported()) {
- std::unique_ptr<gl::GLFence> glFence{gl::GLFence::Create()};
+ if (!glFence && gl::GLContext::GetCurrent() && gl::GLFence::IsSupported())
+ glFence = gl::GLFence::Create();
+ if (glFence)
return base::MakeRefCounted<CompositorResourceFence>(glFence->Transfer());
- }
return nullptr;
}
diff --git a/src/core/compositor/compositor_resource_fence.h b/src/core/compositor/compositor_resource_fence.h
index 1c2ea3695..196297f78 100644
--- a/src/core/compositor/compositor_resource_fence.h
+++ b/src/core/compositor/compositor_resource_fence.h
@@ -60,7 +60,7 @@ public:
void release();
// May be used only by GPU thread.
- static scoped_refptr<CompositorResourceFence> create();
+ static scoped_refptr<CompositorResourceFence> create(std::unique_ptr<gl::GLFence> glFence = nullptr);
private:
gl::TransferableFence m_sync;
diff --git a/src/core/compositor/compositor_resource_tracker.h b/src/core/compositor/compositor_resource_tracker.h
index 887309395..080891e5f 100644
--- a/src/core/compositor/compositor_resource_tracker.h
+++ b/src/core/compositor/compositor_resource_tracker.h
@@ -40,12 +40,13 @@
#ifndef COMPOSITOR_RESOURCE_TRACKER_H
#define COMPOSITOR_RESOURCE_TRACKER_H
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/containers/flat_set.h"
+
#include "compositor_resource.h"
#include "locked_ptr.h"
-#include <base/callback.h>
-#include <base/containers/flat_set.h>
-
#include <atomic>
#include <vector>
diff --git a/src/core/compositor/delegated_frame_node.cpp b/src/core/compositor/delegated_frame_node.cpp
index 5f474cbfb..19e8d1b82 100644
--- a/src/core/compositor/delegated_frame_node.cpp
+++ b/src/core/compositor/delegated_frame_node.cpp
@@ -195,12 +195,10 @@ public:
{
Q_ASSERT(layer);
Q_ASSERT(m_nodeIterator != m_sceneGraphNodes->end());
- QSGInternalImageNode *imageNode = static_cast<QSGInternalImageNode*>(*m_nodeIterator++);
- imageNode->setTargetRect(rect);
- imageNode->setInnerTargetRect(rect);
- imageNode->setSubSourceRect(layer->convertToNormalizedSourceRect(sourceRect));
+ QSGImageNode *imageNode = static_cast<QSGImageNode*>(*m_nodeIterator++);
+ imageNode->setRect(rect);
+ imageNode->setSourceRect(sourceRect);
imageNode->setTexture(layer);
- imageNode->update();
}
void setupTextureContentNode(QSGTexture *texture, const QRect &rect, const QRectF &sourceRect,
@@ -281,13 +279,10 @@ public:
QSGNode *layerChain) override
{
Q_ASSERT(layer);
- // Only QSGInternalImageNode currently supports QSGLayer textures.
- QSGInternalImageNode *imageNode = m_apiDelegate->createInternalImageNode();
- imageNode->setTargetRect(rect);
- imageNode->setInnerTargetRect(rect);
- imageNode->setSubSourceRect(layer->convertToNormalizedSourceRect(sourceRect));
+ QSGImageNode *imageNode = m_apiDelegate->createImageNode();
+ imageNode->setRect(rect);
+ imageNode->setSourceRect(sourceRect);
imageNode->setTexture(layer);
- imageNode->update();
layerChain->appendChildNode(imageNode);
m_sceneGraphNodes->append(imageNode);
@@ -953,7 +948,7 @@ void DelegatedFrameNode::handleQuad(
initAndHoldTexture(resource, quad->ShouldDrawWithBlending(), apiDelegate, GL_TEXTURE_EXTERNAL_OES));
QMatrix4x4 qMatrix;
- convertToQt(squad->matrix.matrix(), qMatrix);
+// convertToQt(squad->matrix.matrix(), qMatrix);
nodeHandler->setupStreamVideoNode(texture, toQt(squad->rect), qMatrix, currentLayerChain);
break;
#endif // GL_OES_EGL_image_external
diff --git a/src/core/compositor/display_consumer.h b/src/core/compositor/display_consumer.h
new file mode 100644
index 000000000..d220088ad
--- /dev/null
+++ b/src/core/compositor/display_consumer.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DISPLAY_CONSUMER_H
+#define DISPLAY_CONSUMER_H
+
+#include "qtwebenginecoreglobal_p.h"
+
+namespace QtWebEngineCore {
+
+// Receives composited frames for display.
+class DisplayConsumer
+{
+public:
+ // Schedule a call to updatePaintNode soon.
+ //
+ // Called on the consumer thread.
+ virtual void scheduleUpdate() = 0;
+
+protected:
+ ~DisplayConsumer() {}
+};
+
+} // namespace QtWebEngineCore
+
+#endif // !DISPLAY_CONSUMER_H
diff --git a/src/core/compositor/display_frame_sink.cpp b/src/core/compositor/display_frame_sink.cpp
new file mode 100644
index 000000000..945600299
--- /dev/null
+++ b/src/core/compositor/display_frame_sink.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "display_frame_sink.h"
+
+#include <QMap>
+
+namespace QtWebEngineCore {
+
+namespace {
+
+class DisplayFrameSinkMap
+{
+public:
+ static DisplayFrameSinkMap *instance()
+ {
+ static DisplayFrameSinkMap map;
+ return &map;
+ }
+
+ scoped_refptr<DisplayFrameSink> findOrCreate(viz::FrameSinkId frameSinkId)
+ {
+ QMutexLocker locker(&m_mutex);
+ auto it = m_map.find(frameSinkId);
+ if (it == m_map.end())
+ it = m_map.insert(frameSinkId, new DisplayFrameSink(frameSinkId));
+ return *it;
+ }
+
+ void remove(viz::FrameSinkId frameSinkId)
+ {
+ QMutexLocker locker(&m_mutex);
+ m_map.remove(frameSinkId);
+ }
+
+private:
+ mutable QMutex m_mutex;
+ QMap<viz::FrameSinkId, DisplayFrameSink *> m_map;
+};
+
+} // namespace
+
+// static
+scoped_refptr<DisplayFrameSink> DisplayFrameSink::findOrCreate(viz::FrameSinkId frameSinkId)
+{
+ return DisplayFrameSinkMap::instance()->findOrCreate(frameSinkId);
+}
+
+DisplayFrameSink::DisplayFrameSink(viz::FrameSinkId frameSinkId)
+ : m_frameSinkId(frameSinkId)
+{
+ DCHECK(m_frameSinkId.is_valid());
+}
+
+DisplayFrameSink::~DisplayFrameSink()
+{
+ DisplayFrameSinkMap::instance()->remove(m_frameSinkId);
+}
+
+void DisplayFrameSink::connect(DisplayConsumer *consumer)
+{
+ QMutexLocker locker(&m_mutex);
+ DCHECK(m_consumer == nullptr);
+ m_consumer = consumer;
+}
+
+void DisplayFrameSink::connect(DisplayProducer *producer)
+{
+ QMutexLocker locker(&m_mutex);
+ DCHECK(m_producer == nullptr);
+ m_producer = producer;
+}
+
+void DisplayFrameSink::disconnect(DisplayConsumer *consumer)
+{
+ QMutexLocker locker(&m_mutex);
+ DCHECK(m_consumer == consumer);
+ m_consumer = nullptr;
+}
+
+void DisplayFrameSink::disconnect(DisplayProducer *producer)
+{
+ QMutexLocker locker(&m_mutex);
+ DCHECK(m_producer == producer);
+ m_producer = nullptr;
+}
+
+void DisplayFrameSink::scheduleUpdate()
+{
+ QMutexLocker locker(&m_mutex);
+ if (m_consumer)
+ m_consumer->scheduleUpdate();
+}
+
+QSGNode *DisplayFrameSink::updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate)
+{
+ QMutexLocker locker(&m_mutex);
+ QSGNode *newNode = oldNode;
+ if (m_producer)
+ newNode = m_producer->updatePaintNode(oldNode, delegate);
+ return newNode;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/display_frame_sink.h b/src/core/compositor/display_frame_sink.h
new file mode 100644
index 000000000..f620dc4f2
--- /dev/null
+++ b/src/core/compositor/display_frame_sink.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DISPLAY_FRAME_SINK_H
+#define DISPLAY_FRAME_SINK_H
+
+#include "display_consumer.h"
+#include "display_producer.h"
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
+#include "components/viz/common/surfaces/frame_sink_id.h"
+
+#include <QMutex>
+
+namespace QtWebEngineCore {
+
+// Connects a DisplayConsumer with a DisplayProducer.
+class DisplayFrameSink final : public base::RefCountedThreadSafe<DisplayFrameSink>
+{
+public:
+ static scoped_refptr<DisplayFrameSink> findOrCreate(viz::FrameSinkId frameSinkId);
+ DisplayFrameSink(viz::FrameSinkId frameSinkId);
+ ~DisplayFrameSink();
+ void connect(DisplayConsumer *consumer);
+ void connect(DisplayProducer *producer);
+ void disconnect(DisplayConsumer *consumer);
+ void disconnect(DisplayProducer *producer);
+ void scheduleUpdate();
+ QSGNode *updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate);
+
+private:
+ const viz::FrameSinkId m_frameSinkId;
+ mutable QMutex m_mutex;
+ DisplayProducer *m_producer = nullptr;
+ DisplayConsumer *m_consumer = nullptr;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // !DISPLAY_FRAME_SINK_H
diff --git a/src/core/compositor/display_gl_output_surface.cpp b/src/core/compositor/display_gl_output_surface.cpp
new file mode 100644
index 000000000..5a78b8322
--- /dev/null
+++ b/src/core/compositor/display_gl_output_surface.cpp
@@ -0,0 +1,292 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "display_gl_output_surface.h"
+
+#include "chromium_gpu_helper.h"
+
+#include "base/threading/thread_task_runner_handle.h"
+#include "components/viz/service/display/display.h"
+#include "components/viz/service/display/output_surface_frame.h"
+#include "gpu/command_buffer/client/gles2_implementation.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/texture_base.h"
+#include "gpu/ipc/in_process_command_buffer.h"
+#include "ui/gl/color_space_utils.h"
+
+namespace QtWebEngineCore {
+
+DisplayGLOutputSurface::DisplayGLOutputSurface(
+ scoped_refptr<viz::VizProcessContextProvider> contextProvider,
+ viz::UpdateVSyncParametersCallback callback)
+ : OutputSurface(contextProvider)
+ , m_commandBuffer(contextProvider->command_buffer())
+ , m_gl(contextProvider->ContextGL())
+{
+ capabilities_.uses_default_gl_framebuffer = false;
+ m_gl->GenFramebuffers(1, &m_fboId);
+ contextProvider->SetUpdateVSyncParametersCallback(std::move(callback));
+}
+
+DisplayGLOutputSurface::~DisplayGLOutputSurface()
+{
+ m_gl->DeleteFramebuffers(1, &m_fboId);
+ if (m_sink)
+ m_sink->disconnect(this);
+}
+
+// Called from viz::Display::Initialize.
+void DisplayGLOutputSurface::BindToClient(viz::OutputSurfaceClient *client)
+{
+ m_display = static_cast<viz::Display *>(client);
+ m_sink = DisplayFrameSink::findOrCreate(m_display->frame_sink_id());
+ m_sink->connect(this);
+}
+
+// Triggered by ui::Compositor::SetVisible(true).
+void DisplayGLOutputSurface::EnsureBackbuffer()
+{
+}
+
+// Triggered by ui::Compositor::SetVisible(false). Framebuffer must be cleared.
+void DisplayGLOutputSurface::DiscardBackbuffer()
+{
+ NOTIMPLEMENTED();
+ // m_gl->DiscardBackbufferCHROMIUM();
+}
+
+// Called from viz::DirectRenderer::DrawFrame before rendering starts, but only
+// if the parameters differ from the previous Reshape call.
+//
+// Parameters:
+//
+// - sizeInPixels comes from ui::Compositor::SetScaleAndSize via
+// viz::HostContextFactoryPrivate::ResizeDisplay.
+//
+// - devicePixelRatio comes from viz::CompositorFrame::device_scale_factor()
+// via viz::RootCompositorFrameSinkImpl::SubmitCompositorFrame and
+// viz::Display::SetLocalSurfaceId.
+//
+// - colorSpace and hasAlpha correspond to the color_space and
+// has_transparent_background properties of the root viz::RenderPass.
+//
+// - useStencil should create a stencil buffer, but this is only needed for
+// overdraw feedback (--show-overdraw-feedback), so it's safe to ignore.
+// Accordingly, capabilities_.supports_stencil should be set to false.
+//
+void DisplayGLOutputSurface::Reshape(const gfx::Size &sizeInPixels,
+ float devicePixelRatio,
+ const gfx::ColorSpace &colorSpace,
+ bool hasAlpha,
+ bool /*useStencil*/)
+{
+ m_currentShape = Shape{sizeInPixels, devicePixelRatio, colorSpace, hasAlpha};
+ m_gl->ResizeCHROMIUM(sizeInPixels.width(), sizeInPixels.height(), devicePixelRatio,
+ gl::ColorSpaceUtils::GetGLColorSpace(colorSpace), hasAlpha);
+}
+
+std::unique_ptr<DisplayGLOutputSurface::Buffer> DisplayGLOutputSurface::makeBuffer(const Shape &shape)
+{
+ std::unique_ptr<Buffer> buffer = std::make_unique<Buffer>(this);
+ buffer->shape = shape;
+ m_gl->GenTextures(1, &buffer->clientId);
+ m_gl->BindTexture(GL_TEXTURE_2D, buffer->clientId);
+ m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ uint32_t width = shape.sizeInPixels.width();
+ uint32_t height = shape.sizeInPixels.height();
+ uint32_t format = shape.hasAlpha ? GL_RGBA : GL_RGB;
+ m_gl->TexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, nullptr);
+ return buffer;
+}
+
+void DisplayGLOutputSurface::deleteBufferResources(Buffer *buffer)
+{
+ m_gl->DeleteTextures(1, &buffer->clientId);
+}
+
+// Called by viz::GLRenderer during rendering whenever it switches to the root
+// render pass.
+void DisplayGLOutputSurface::BindFramebuffer()
+{
+ if (!m_backBuffer || m_backBuffer->shape != m_currentShape)
+ m_backBuffer = makeBuffer(m_currentShape);
+
+ m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fboId);
+ m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_backBuffer->clientId, 0);
+}
+
+// Called from viz::Display::DrawAndSwap after rendering.
+//
+// Parameters:
+//
+// - frame.size is the same as the size given to Reshape.
+//
+// - frame.sub_buffer_rect and frame.content_bounds are never used since these
+// are only enabled if gl::GLSurface::SupportsPostSubBuffer() or
+// gl::GLSurface::SupportsSwapBuffersWithBounds() are true, respectively,
+// but this not the case for any offscreen gl::GLSurface.
+//
+// - frame.latency_info is viz::CompositorFrame::metadata.latency_info.
+void DisplayGLOutputSurface::SwapBuffers(viz::OutputSurfaceFrame frame)
+{
+ DCHECK(frame.size == m_currentShape.sizeInPixels);
+ DCHECK(!frame.sub_buffer_rect.has_value());
+ DCHECK(frame.content_bounds.empty());
+ DCHECK(m_backBuffer);
+
+ m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fboId);
+ m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
+ gpu::SyncToken syncToken;
+ m_gl->GenSyncTokenCHROMIUM(syncToken.GetData());
+
+ unsigned int clientId = m_backBuffer->clientId;
+
+ // Now some thread-hopping:
+ //
+ // - We start here on the viz thread (client side of command buffer).
+ //
+ // - Then we'll jump to the gpu thread (service side of command buffer) to
+ // get the real OpenGL texture id.
+ //
+ // - Then we'll get a call from the Qt Quick Scene Graph thread (could be
+ // a separate thread or the main thread).
+ //
+ // - Finally we'll return to the viz thread to acknowledge the swap.
+
+ {
+ QMutexLocker locker(&m_mutex);
+ m_taskRunner = base::ThreadTaskRunnerHandle::Get();
+ m_middleBuffer = std::move(m_backBuffer);
+ m_middleBuffer->serviceId = 0;
+ }
+
+ m_commandBuffer->GetTextureQt(
+ clientId,
+ base::BindOnce(&DisplayGLOutputSurface::swapBuffersOnGpuThread, base::Unretained(this)),
+ std::vector<gpu::SyncToken>{syncToken});
+}
+
+void DisplayGLOutputSurface::swapBuffersOnGpuThread(unsigned int id, std::unique_ptr<gl::GLFence> fence)
+{
+ {
+ QMutexLocker locker(&m_mutex);
+ m_middleBuffer->serviceId = id;
+ m_middleBuffer->fence = CompositorResourceFence::create(std::move(fence));
+ }
+
+ m_sink->scheduleUpdate();
+}
+
+void DisplayGLOutputSurface::swapBuffersOnVizThread()
+{
+ {
+ QMutexLocker locker(&m_mutex);
+ m_backBuffer = std::move(m_middleBuffer);
+ }
+
+ m_display->DidReceiveSwapBuffersAck();
+ m_display->DidReceivePresentationFeedback(
+ gfx::PresentationFeedback(base::TimeTicks::Now(), base::TimeDelta(),
+ gfx::PresentationFeedback::Flags::kVSync));
+}
+
+void DisplayGLOutputSurface::SetDrawRectangle(const gfx::Rect &)
+{
+}
+
+// Returning nullptr here effectively disables viz::OverlayProcessor.
+viz::OverlayCandidateValidator *DisplayGLOutputSurface::GetOverlayCandidateValidator() const
+{
+ return nullptr;
+}
+
+// Returning true here will cause viz::GLRenderer to try to render the output
+// surface as an overlay plane (see viz::DirectRenderer::DrawFrame and
+// viz::GLRenderer::ScheduleOverlays).
+bool DisplayGLOutputSurface::IsDisplayedAsOverlayPlane() const
+{
+ return false;
+}
+
+// Only used if IsDisplayedAsOverlayPlane was true (called from
+// viz::GLRenderer::ScheduleOverlays).
+unsigned DisplayGLOutputSurface::GetOverlayTextureId() const
+{
+ return 0;
+}
+
+// Only used if IsDisplayedAsOverlayPlane was true (called from
+// viz::DirectRender::DrawFrame).
+gfx::BufferFormat DisplayGLOutputSurface::GetOverlayBufferFormat() const
+{
+ return gfx::BufferFormat();
+}
+
+// Called by viz::GLRenderer but always false in all implementations except for
+// android_webview::ParentOutputSurface.
+bool DisplayGLOutputSurface::HasExternalStencilTest() const
+{
+ return false;
+}
+
+// Only called if HasExternalStencilTest was true. Dead code?
+void DisplayGLOutputSurface::ApplyExternalStencil()
+{
+ NOTREACHED();
+}
+
+// Called from GLRenderer::GetFramebufferCopyTextureFormat when using
+// glCopyTexSubImage2D on our framebuffer.
+uint32_t DisplayGLOutputSurface::GetFramebufferCopyTextureFormat()
+{
+ return GL_RGBA;
+}
+
+// Called from viz::DirectRenderer::DrawFrame, only used for overlays.
+unsigned DisplayGLOutputSurface::UpdateGpuFence()
+{
+ NOTREACHED();
+ return 0;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/display_gl_output_surface.h b/src/core/compositor/display_gl_output_surface.h
new file mode 100644
index 000000000..c42a6630a
--- /dev/null
+++ b/src/core/compositor/display_gl_output_surface.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DISPLAY_GL_OUTPUT_SURFACE_H
+#define DISPLAY_GL_OUTPUT_SURFACE_H
+
+#include "compositor_resource_fence.h"
+#include "display_frame_sink.h"
+
+#include "components/viz/common/display/update_vsync_parameters_callback.h"
+#include "components/viz/service/display/output_surface.h"
+#include "components/viz/service/display_embedder/viz_process_context_provider.h"
+#include "gpu/command_buffer/common/mailbox.h"
+#include "gpu/command_buffer/common/sync_token.h"
+
+namespace viz {
+class Display;
+class SyntheticBeginFrameSource;
+} // namespace viz
+
+namespace QtWebEngineCore {
+
+// NOTE: Some methods are defined in display_gl_output_surface_qsg.cpp due
+// to conflicts between Qt & Chromium OpenGL APIs.
+class DisplayGLOutputSurface final : public viz::OutputSurface, public DisplayProducer
+{
+public:
+ DisplayGLOutputSurface(
+ scoped_refptr<viz::VizProcessContextProvider> contextProvider,
+ viz::UpdateVSyncParametersCallback callback);
+ ~DisplayGLOutputSurface() override;
+
+ // Overridden from viz::OutputSurface.
+ void BindToClient(viz::OutputSurfaceClient *client) override;
+ void EnsureBackbuffer() override;
+ void DiscardBackbuffer() override;
+ void BindFramebuffer() override;
+ void SetDrawRectangle(const gfx::Rect &drawRect) override;
+ viz::OverlayCandidateValidator *GetOverlayCandidateValidator() const override;
+ bool IsDisplayedAsOverlayPlane() const override;
+ unsigned GetOverlayTextureId() const override;
+ gfx::BufferFormat GetOverlayBufferFormat() const override;
+ void Reshape(const gfx::Size &size,
+ float devicePixelRatio,
+ const gfx::ColorSpace &colorSpace,
+ bool hasAlpha,
+ bool useStencil) override;
+ bool HasExternalStencilTest() const override;
+ void ApplyExternalStencil() override;
+ uint32_t GetFramebufferCopyTextureFormat() override;
+ void SwapBuffers(viz::OutputSurfaceFrame frame) override;
+ unsigned UpdateGpuFence() override;
+
+ // Overridden from DisplayProducer.
+ QSGNode *updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate) override;
+
+private:
+ struct Shape
+ {
+ gfx::Size sizeInPixels;
+ float devicePixelRatio;
+ gfx::ColorSpace colorSpace;
+ bool hasAlpha;
+
+ bool operator==(const Shape &that) const
+ {
+ return (sizeInPixels == that.sizeInPixels &&
+ devicePixelRatio == that.devicePixelRatio &&
+ colorSpace == that.colorSpace &&
+ hasAlpha == that.hasAlpha);
+ }
+ bool operator!=(const Shape &that) const { return !(*this == that); }
+ };
+
+ struct Buffer
+ {
+ DisplayGLOutputSurface *parent;
+ Shape shape;
+ uint32_t clientId = 0;
+ uint32_t serviceId = 0;
+ scoped_refptr<CompositorResourceFence> fence;
+
+ Buffer(DisplayGLOutputSurface *parent) : parent(parent) {}
+ ~Buffer() { parent->deleteBufferResources(this); }
+ };
+
+ class Texture;
+
+ void swapBuffersOnGpuThread(unsigned int id, std::unique_ptr<gl::GLFence> fence);
+ void swapBuffersOnVizThread();
+
+ std::unique_ptr<Buffer> makeBuffer(const Shape &shape);
+ void deleteBufferResources(Buffer *buffer);
+ void attachBuffer();
+ void detachBuffer();
+
+ gpu::InProcessCommandBuffer *const m_commandBuffer;
+ gpu::gles2::GLES2Interface *const m_gl;
+ mutable QMutex m_mutex;
+ uint32_t m_fboId = 0;
+ viz::Display *m_display = nullptr;
+ scoped_refptr<DisplayFrameSink> m_sink;
+ Shape m_currentShape;
+ std::unique_ptr<Buffer> m_backBuffer;
+ std::unique_ptr<Buffer> m_middleBuffer;
+ std::unique_ptr<Buffer> m_frontBuffer;
+ scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // !DISPLAY_GL_OUTPUT_SURFACE_H
diff --git a/src/core/compositor/display_gl_output_surface_qsg.cpp b/src/core/compositor/display_gl_output_surface_qsg.cpp
new file mode 100644
index 000000000..2f7b3de84
--- /dev/null
+++ b/src/core/compositor/display_gl_output_surface_qsg.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "display_gl_output_surface.h"
+
+#include "compositor_resource_fence.h"
+#include "render_widget_host_view_qt_delegate.h"
+#include "type_conversion.h"
+
+#include <QOpenGLFunctions>
+#include <QSGImageNode>
+#include <QSGTexture>
+
+namespace QtWebEngineCore {
+
+class DisplayGLOutputSurface::Texture final : public QSGTexture
+{
+public:
+ Texture(uint32_t id, QSize sizeInPixels, bool hasAlphaChannel, scoped_refptr<CompositorResourceFence> fence)
+ : m_id(id)
+ , m_sizeInPixels(sizeInPixels)
+ , m_hasAlphaChannel(hasAlphaChannel)
+ , m_fence(std::move(fence))
+ {
+ }
+
+ // QSGTexture:
+ int textureId() const override { return m_id; }
+ QSize textureSize() const override { return m_sizeInPixels; }
+ bool hasAlphaChannel() const override { return m_hasAlphaChannel; }
+ bool hasMipmaps() const override { return false; }
+ void bind() override
+ {
+ if (m_fence) {
+ m_fence->wait();
+ m_fence.reset();
+ }
+
+ QOpenGLContext *context = QOpenGLContext::currentContext();
+ QOpenGLFunctions *funcs = context->functions();
+ funcs->glBindTexture(GL_TEXTURE_2D, m_id);
+ }
+
+private:
+ uint32_t m_id;
+ QSize m_sizeInPixels;
+ bool m_hasAlphaChannel;
+ scoped_refptr<CompositorResourceFence> m_fence;
+};
+
+QSGNode *DisplayGLOutputSurface::updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate)
+{
+ {
+ QMutexLocker locker(&m_mutex);
+ if (m_middleBuffer && m_middleBuffer->serviceId) {
+ std::swap(m_middleBuffer, m_frontBuffer);
+ m_taskRunner->PostTask(
+ FROM_HERE,
+ base::BindOnce(&DisplayGLOutputSurface::swapBuffersOnVizThread, base::Unretained(this)));
+ m_taskRunner.reset();
+ }
+ }
+
+ if (!m_frontBuffer)
+ return oldNode;
+
+ auto node = static_cast<QSGImageNode *>(oldNode);
+ if (!node)
+ node = delegate->createImageNode();
+
+ QSize sizeInPixels = toQt(m_frontBuffer->shape.sizeInPixels);
+ QSizeF sizeInDips = QSizeF(sizeInPixels) / m_frontBuffer->shape.devicePixelRatio;
+ QRectF rectInDips(QPointF(0, 0), sizeInDips);
+ node->setRect(rectInDips);
+ node->setOwnsTexture(true);
+ node->setTexture(new Texture(m_frontBuffer->serviceId,
+ sizeInPixels,
+ m_frontBuffer->shape.hasAlpha,
+ m_frontBuffer->fence));
+ node->setTextureCoordinatesTransform(QSGImageNode::MirrorVertically);
+
+ return node;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/display_overrides.cpp b/src/core/compositor/display_overrides.cpp
new file mode 100644
index 000000000..4547bb04b
--- /dev/null
+++ b/src/core/compositor/display_overrides.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "display_gl_output_surface.h"
+#include "display_software_output_surface.h"
+
+#include "components/viz/service/display_embedder/gpu_display_provider.h"
+#include "gpu/ipc/in_process_command_buffer.h"
+
+std::unique_ptr<viz::OutputSurface>
+viz::GpuDisplayProvider::CreateGLOutputSurface(
+ scoped_refptr<VizProcessContextProvider> context_provider,
+ UpdateVSyncParametersCallback update_vsync_callback)
+{
+ return std::make_unique<QtWebEngineCore::DisplayGLOutputSurface>(
+ std::move(context_provider), std::move(update_vsync_callback));
+}
+
+std::unique_ptr<viz::OutputSurface>
+viz::GpuDisplayProvider::CreateSoftwareOutputSurface(
+ UpdateVSyncParametersCallback update_vsync_callback)
+{
+ return std::make_unique<QtWebEngineCore::DisplaySoftwareOutputSurface>(std::move(update_vsync_callback));
+}
+
+void gpu::InProcessCommandBuffer::GetTextureQt(
+ unsigned int client_id,
+ GetTextureCallback callback,
+ const std::vector<SyncToken>& sync_token_fences)
+{
+ ScheduleGpuTask(base::BindOnce(&InProcessCommandBuffer::GetTextureQtOnGpuThread,
+ gpu_thread_weak_ptr_factory_.GetWeakPtr(),
+ client_id,
+ std::move(callback)),
+ sync_token_fences);
+}
+
+void gpu::InProcessCommandBuffer::GetTextureQtOnGpuThread(
+ unsigned int client_id, GetTextureCallback callback)
+{
+ MakeCurrent();
+ gpu::TextureBase *texture = decoder_->GetTextureBase(client_id);
+ std::move(callback).Run(texture ? texture->service_id() : 0, gl::GLFence::Create());
+}
diff --git a/src/core/compositor/display_producer.h b/src/core/compositor/display_producer.h
new file mode 100644
index 000000000..5de09d2d2
--- /dev/null
+++ b/src/core/compositor/display_producer.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DISPLAY_PRODUCER_H
+#define DISPLAY_PRODUCER_H
+
+#include "qtwebenginecoreglobal_p.h"
+
+QT_BEGIN_NAMESPACE
+class QSGNode;
+QT_END_NAMESPACE
+
+namespace QtWebEngineCore {
+class RenderWidgetHostViewQtDelegate;
+
+// Produces composited frames for display.
+class DisplayProducer
+{
+public:
+ // Generate scene graph nodes for the current frame.
+ //
+ // If this is a scheduled update (that is, scheduleUpdate was called
+ // earlier), then updatePaintNode will generate nodes for a new frame.
+ // Otherwise, it will just regenerate nodes for the old frame.
+ virtual QSGNode *updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate) = 0;
+
+protected:
+ ~DisplayProducer() {}
+};
+
+} // namespace QtWebEngineCore
+
+#endif // !DISPLAY_PRODUCER_H
diff --git a/src/core/compositor/display_software_output_surface.cpp b/src/core/compositor/display_software_output_surface.cpp
new file mode 100644
index 000000000..13f8e8f38
--- /dev/null
+++ b/src/core/compositor/display_software_output_surface.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "display_software_output_surface.h"
+
+#include "display_frame_sink.h"
+#include "render_widget_host_view_qt_delegate.h"
+#include "type_conversion.h"
+
+#include "base/threading/thread_task_runner_handle.h"
+#include "components/viz/service/display/display.h"
+#include "components/viz/service/display/output_surface_frame.h"
+
+#include <QMutex>
+#include <QPainter>
+#include <QSGImageNode>
+
+namespace QtWebEngineCore {
+
+class DisplaySoftwareOutputSurface::Device final : public viz::SoftwareOutputDevice, public DisplayProducer
+{
+public:
+ ~Device();
+
+ // Called from DisplaySoftwareOutputSurface.
+ void bind(viz::FrameSinkId frameSinkId);
+
+ // Overridden from viz::SoftwareOutputDevice.
+ void Resize(const gfx::Size &sizeInPixels, float devicePixelRatio) override;
+ void OnSwapBuffers(base::OnceClosure swapCompletionCallback) override;
+
+ // Overridden from DisplayProducer.
+ QSGNode *updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate) override;
+
+private:
+ mutable QMutex m_mutex;
+ scoped_refptr<DisplayFrameSink> m_sink;
+ float m_devicePixelRatio = 1.0;
+ scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
+ base::OnceClosure m_swapCompletionCallback;
+ QImage m_image;
+ float m_imageDevicePixelRatio = 1.0;
+};
+
+DisplaySoftwareOutputSurface::Device::~Device()
+{
+ if (m_sink)
+ m_sink->disconnect(this);
+}
+
+void DisplaySoftwareOutputSurface::Device::bind(viz::FrameSinkId frameSinkId)
+{
+ m_sink = DisplayFrameSink::findOrCreate(frameSinkId);
+ m_sink->connect(this);
+}
+
+void DisplaySoftwareOutputSurface::Device::Resize(const gfx::Size &sizeInPixels, float devicePixelRatio)
+{
+ if (viewport_pixel_size_ == sizeInPixels && m_devicePixelRatio == devicePixelRatio)
+ return;
+ m_devicePixelRatio = devicePixelRatio;
+ viewport_pixel_size_ = sizeInPixels;
+ surface_ = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(sizeInPixels.width(), sizeInPixels.height()));
+}
+
+void DisplaySoftwareOutputSurface::Device::OnSwapBuffers(base::OnceClosure swapCompletionCallback)
+{
+ QMutexLocker locker(&m_mutex);
+ m_taskRunner = base::ThreadTaskRunnerHandle::Get();
+ m_swapCompletionCallback = std::move(swapCompletionCallback);
+ m_sink->scheduleUpdate();
+}
+
+inline QImage::Format imageFormat(SkColorType colorType)
+{
+ switch (colorType) {
+ case kBGRA_8888_SkColorType:
+ return QImage::Format_ARGB32_Premultiplied;
+ case kRGBA_8888_SkColorType:
+ return QImage::Format_RGBA8888_Premultiplied;
+ default:
+ Q_UNREACHABLE();
+ return QImage::Format_ARGB32_Premultiplied;
+ }
+}
+
+QSGNode *DisplaySoftwareOutputSurface::Device::updatePaintNode(
+ QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate)
+{
+ QMutexLocker locker(&m_mutex);
+
+ // Delete old node to make sure refcount of m_image is at most 1.
+ delete oldNode;
+ QSGImageNode *node = delegate->createImageNode();
+
+ if (m_swapCompletionCallback) {
+ SkPixmap skPixmap;
+ surface_->peekPixels(&skPixmap);
+ QImage image(reinterpret_cast<const uchar *>(skPixmap.addr()),
+ viewport_pixel_size_.width(), viewport_pixel_size_.height(),
+ skPixmap.rowBytes(), imageFormat(skPixmap.colorType()));
+ if (m_image.size() == image.size()) {
+ QRect damageRect = toQt(damage_rect_);
+ QPainter(&m_image).drawImage(damageRect, image, damageRect);
+ } else {
+ m_image = image;
+ m_image.detach();
+ }
+ m_imageDevicePixelRatio = m_devicePixelRatio;
+ m_taskRunner->PostTask(FROM_HERE, std::move(m_swapCompletionCallback));
+ m_taskRunner.reset();
+ }
+
+ QSizeF sizeInDips = QSizeF(m_image.size()) / m_imageDevicePixelRatio;
+ node->setRect(QRectF(QPointF(0, 0), sizeInDips));
+ node->setOwnsTexture(true);
+ node->setTexture(delegate->createTextureFromImage(m_image));
+
+ return node;
+}
+
+DisplaySoftwareOutputSurface::DisplaySoftwareOutputSurface(viz::UpdateVSyncParametersCallback callback)
+ : SoftwareOutputSurface(std::make_unique<Device>(), std::move(callback))
+{}
+
+DisplaySoftwareOutputSurface::~DisplaySoftwareOutputSurface() {}
+
+// Called from viz::Display::Initialize.
+void DisplaySoftwareOutputSurface::BindToClient(viz::OutputSurfaceClient *client)
+{
+ auto display = static_cast<viz::Display *>(client);
+ auto device = static_cast<Device *>(software_device());
+ device->bind(display->frame_sink_id());
+ SoftwareOutputSurface::BindToClient(client);
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor/display_software_output_surface.h b/src/core/compositor/display_software_output_surface.h
new file mode 100644
index 000000000..6707c74dc
--- /dev/null
+++ b/src/core/compositor/display_software_output_surface.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DISPLAY_SOFTWARE_OUTPUT_SURFACE_H
+#define DISPLAY_SOFTWARE_OUTPUT_SURFACE_H
+
+#include "components/viz/service/display_embedder/software_output_surface.h"
+
+namespace QtWebEngineCore {
+
+class DisplaySoftwareOutputSurface final : public viz::SoftwareOutputSurface
+{
+public:
+ DisplaySoftwareOutputSurface(viz::UpdateVSyncParametersCallback callback);
+ ~DisplaySoftwareOutputSurface() override;
+
+ // Overridden from viz::SoftwareOutputSurface.
+ void BindToClient(viz::OutputSurfaceClient *client) override;
+
+private:
+ class Device;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // !DISPLAY_SOFTWARE_OUTPUT_SURFACE_H
diff --git a/src/core/configure.json b/src/core/configure.json
index be686850b..9ee66bf61 100644
--- a/src/core/configure.json
+++ b/src/core/configure.json
@@ -1,11 +1,12 @@
{
"module": "webenginecore",
"depends": [
+ "buildtools-private",
"core-private",
"gui-private",
"printsupport"
],
- "condition": "module.gui",
+ "condition": "features.build-qtwebengine-core && features.webengine-core-support",
"testDir": "../../config.tests",
"commandline": {
"options": {
@@ -28,8 +29,6 @@
"webengine-v8-snapshot": "boolean",
"webengine-webchannel": "boolean",
"webengine-kerberos": "boolean",
- "webengine-widgets": "boolean",
- "webengine-qml": "boolean",
"alsa": { "type": "boolean", "name": "webengine-alsa" },
"pulseaudio": { "type": "boolean", "name": "webengine-pulseaudio" },
"ffmpeg": { "type": "enum", "name": "webengine-system-ffmpeg", "values": { "system": "yes", "qt": "no" } },
@@ -45,94 +44,17 @@
},
"libraries": {
- "webengine-dbus": {
- "label": "d-bus",
- "sources": [
- { "type": "pkgConfig", "args": "dbus-1" }
- ]
- },
- "webengine-fontconfig": {
- "label": "fontconfig",
- "sources": [
- { "type": "pkgConfig", "args": "fontconfig" }
- ]
- },
- "webengine-libdrm": {
- "label": "libdrm",
- "sources": [
- { "type": "pkgConfig", "args": "libdrm" }
- ]
- },
- "webengine-xcomposite": {
- "label": "xcomposite",
- "sources": [
- { "type": "pkgConfig", "args": "xcomposite" }
- ]
- },
- "webengine-xcursor": {
- "label": "xcursor",
- "sources": [
- { "type": "pkgConfig", "args": "xcursor" }
- ]
- },
- "webengine-xi": {
- "label": "xi",
- "sources": [
- { "type": "pkgConfig", "args": "xi" }
- ]
- },
- "webengine-xtst": {
- "label": "xtst",
- "sources": [
- { "type": "pkgConfig", "args": "xtst" }
- ]
- },
- "webengine-harfbuzz": {
- "label": "harfbuzz >= 2.2.0",
- "sources": [
- { "type": "pkgConfig", "args": "harfbuzz >= 2.2.0" }
- ]
- },
- "webengine-glib": {
- "label": "glib-2.0 >= 2.32.0",
- "sources": [
- { "type": "pkgConfig", "args": "glib-2.0 >= 2.32.0" }
- ]
- },
- "webengine-zlib": {
- "label": "zlib",
- "sources": [
- { "type": "pkgConfig", "args": "zlib" }
- ]
- },
- "webengine-minizip": {
- "label": "minizip",
- "sources": [
- { "type": "pkgConfig", "args": "minizip" }
- ]
- },
- "webengine-libevent": {
- "label": "libevent",
- "sources": [
- { "type": "pkgConfig", "args": "libevent" }
- ]
- },
- "webengine-libxml2": {
- "label": "libxml2 and libxslt",
- "sources": [
- { "type": "pkgConfig", "args": "libxml-2.0 libxslt" }
- ]
- },
- "webengine-jsoncpp": {
- "label": "jsoncpp",
- "sources": [
- { "type": "pkgConfig", "args": "jsoncpp" }
- ]
- },
- "webengine-protobuf": {
- "label": "protobuf",
- "sources": [
- { "type": "pkgConfig", "args": "protobuf" }
+ "webengine-alsa": {
+ "label": "alsa",
+ "test": {
+ "tail": [
+ "#if SND_LIB_VERSION < 0x1000a // 1.0.10",
+ "#error Alsa version found too old, require >= 1.0.10",
+ "#endif"
+ ]
+ },
+ "headers" : ["alsa/asoundlib.h"],
+ "sources" : [{ "type": "pkgConfig", "args": "alsa" }
]
},
"webengine-poppler-cpp": {
@@ -141,195 +63,33 @@
{ "type": "pkgConfig", "args": "poppler-cpp" }
]
},
- "pulseaudio": {
+ "webengine-pulseaudio": {
"label": "pulseaudio >= 0.9.10",
"sources": [
{ "type": "pkgConfig", "args": "libpulse >= 0.9.10 libpulse-mainloop-glib" }
]
- },
- "webengine-icu": {
- "label": "icu >= 63",
- "sources": [
- { "type": "pkgConfig", "args": "icu-uc >= 63 icu-i18n >= 63" }
- ]
- },
- "webengine-ffmpeg": {
- "label": "libavcodec libavformat libavutil",
- "sources": [
- { "type": "pkgConfig", "args": "libavcodec libavformat libavutil" }
- ]
- },
- "webengine-opus": {
- "label": "opus",
- "sources": [
- { "type": "pkgConfig", "args": "opus" }
- ]
- },
- "webengine-webp": {
- "label": "libwebp, libwebpmux and libwebpdemux",
- "sources": [
- { "type": "pkgConfig", "args": "libwebp libwebpmux libwebpdemux" }
- ]
- },
- "webengine-nss": {
- "label": "nss >= 3.26",
- "sources": [
- { "type": "pkgConfig", "args": "nss >= 3.26" }
- ]
- },
- "webengine-png": {
- "label": "libpng >= 1.6.0",
- "sources": [
- { "type": "pkgConfig", "args": "libpng >= 1.6.0" }
- ]
- },
- "webengine-jpeglib": {
- "label": "compatible jpeglib",
- "type": "compile",
- "test": {
- "head": [
- "#include <cstdio>",
- "#include <cstring>",
- "extern \"C\" {",
- " #include <jpeglib.h>",
- "}"
- ],
- "main": [
- "JDIMENSION dummy;",
- "jpeg_crop_scanline(nullptr, &dummy, &dummy);",
- "jpeg_skip_scanlines(nullptr, dummy);"
- ]
- },
- "sources": [
- { "type": "pkgConfig", "args": "libjpeg" },
- "-ljpeg"
- ]
- },
- "webengine-lcms2": {
- "label": "lcms2",
- "sources": [
- { "type": "pkgConfig", "args": "lcms2" }
- ]
- },
- "webengine-freetype": {
- "label": "freetype >= 2.4.2",
- "test": {
- "head": [
- "#include <ft2build.h>",
- "#include FT_FREETYPE_H",
- "#if ((FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) < 20402)",
- "# error This version of freetype is too old.",
- "#endif"
- ],
- "main": [
- "FT_Face ft_face = 0;",
- "FT_Reference_Face(ft_face);"
- ]
- },
- "sources": [
- { "type": "pkgConfig", "args": "freetype2" }
- ]
- },
- "webengine-x11" : {
- "label" : "x11",
- "sources": [
- { "type": "pkgConfig", "args": "x11" }
- ]
}
},
"tests" : {
- "webengine-alsa": {
- "label": "alsa",
- "test": "alsa",
- "type": "compile"
- },
"webengine-host-compiler": {
"label": "host compiler",
"test": "hostcompiler",
"host": "true",
"type": "compile"
},
- "webengine-khr": {
- "label": "khr",
- "test": "khr",
- "type": "compile"
- },
- "webengine-libvpx": {
- "label": "libvpx",
- "test": "libvpx",
- "type": "compile"
- },
- "webengine-snappy": {
- "label": "snappy",
- "test": "snappy",
- "type": "compile"
- },
- "webengine-winversion": {
- "label": "winversion",
- "test": "winversion",
- "type": "compile"
- },
- "webengine-protoc": {
- "label": "protoc",
- "type": "detectProtoc"
- },
- "webengine-python2": {
- "label": "python2",
- "type": "detectPython2",
- "log": "location"
- },
"webengine-host-pkg-config": {
"label": "host pkg-config",
"type": "detectHostPkgConfig",
"log": "path"
},
- "webengine-gperf": {
- "label": "gperf",
- "type": "detectGperf"
- },
- "webengine-bison": {
- "label": "bison",
- "type": "detectBison"
- },
- "webengine-flex": {
- "label": "flex",
- "type": "detectFlex"
- },
- "webengine-ninja": {
- "label": "system ninja",
- "type": "detectNinja"
- },
- "webengine-gn": {
- "label": "system gn",
- "type": "detectGn"
- },
"webengine-embedded-build": {
- "label": "embedded",
- "type": "embedded"
- },
- "webengine-re2": {
- "label": "re2",
- "test": "re2",
- "type": "compile"
- },
- "webengine-glibc": {
- "label": "glibc > 2.16",
- "type": "compile",
- "test": "glibc"
- },
- "webengine-libxml2-compatible": {
- "label" : "compatible system libxml2",
- "test" : "xml2",
- "type": "compile"
+ "label": "embedded build",
+ "type": "detectEmbedded"
},
"webengine-sanitizer": {
"label" : "sanitizer support",
"type": "isSanitizerSupported"
},
- "webengine-win-compiler64": {
- "label": "64bit compiler",
- "type": "isWindowsHostCompiler64"
- },
"webengine-arm-thumb" : {
"label": "thumb instruction set",
"type": "hasThumbFlag"
@@ -344,119 +104,7 @@
"flag": "-z,noexecstack"
}
},
-
"features": {
- "webengine-system-fontconfig": {
- "label": "fontconfig",
- "condition": "libs.webengine-fontconfig",
- "output": [ "privateFeature" ]
- },
- "webengine-system-dbus": {
- "label": "dbus",
- "condition": "libs.webengine-dbus",
- "output": [ "privateFeature" ]
- },
- "webengine-system-libdrm": {
- "label": "libdrm",
- "condition": "libs.webengine-libdrm",
- "output": [ "privateFeature" ]
- },
- "webengine-system-xcomposite": {
- "label": "xcomposite",
- "condition": "libs.webengine-xcomposite",
- "output": [ "privateFeature" ]
- },
- "webengine-system-xcursor": {
- "label": "xcursor",
- "condition": "libs.webengine-xcursor",
- "output": [ "privateFeature" ]
- },
- "webengine-system-xi": {
- "label": "xi",
- "condition": "libs.webengine-xi",
- "output": [ "privateFeature" ]
- },
- "webengine-system-xtst": {
- "label": "xtst",
- "condition": "libs.webengine-xtst",
- "output": [ "privateFeature" ]
- },
- "webengine-system-harfbuzz": {
- "label": "harfbuzz",
- "condition": "config.unix && features.system-harfbuzz && libs.webengine-harfbuzz",
- "output": [ "privateFeature" ]
- },
- "webengine-system-glib" : {
- "label": "glib",
- "condition": "config.unix && libs.webengine-glib",
- "output": [ "privateFeature" ]
- },
- "webengine-system-minizip" : {
- "label": "minizip",
- "condition": "config.unix && libs.webengine-minizip",
- "output": [ "privateFeature" ]
- },
- "webengine-system-zlib" : {
- "label": "zlib",
- "condition": "config.unix && features.system-zlib && libs.webengine-zlib",
- "output": [ "privateFeature" ]
- },
- "webengine-system-libevent" : {
- "label": "libevent",
- "condition": "config.unix && libs.webengine-libevent",
- "output": [ "privateFeature" ]
- },
- "webengine-system-jsoncpp" : {
- "label": "jsoncpp",
- "condition": "config.unix && libs.webengine-jsoncpp",
- "output": [ "privateFeature" ]
- },
- "webengine-system-protobuf" : {
- "label": "protobuf",
- "condition": "config.unix && libs.webengine-protobuf && tests.webengine-protoc",
- "output": [ "privateFeature" ]
- },
- "webengine-system-png" : {
- "label": "png",
- "condition": "config.unix && features.system-png && libs.webengine-png",
- "output": [ "privateFeature" ]
- },
- "webengine-system-jpeg" : {
- "label": "JPEG",
- "condition": "config.unix && features.system-jpeg && libs.webengine-jpeglib",
- "output": [ "privateFeature" ]
- },
- "webengine-python2": {
- "label": "python2",
- "condition": "tests.webengine-python2",
- "output": [
- "privateFeature",
- { "type": "varAssign", "name": "QMAKE_PYTHON2", "value": "tests.webengine-python2.location" }
- ]
- },
- "webengine-host-pkg-config": {
- "label": "host-pkg-config",
- "condition": "config.unix && tests.webengine-host-pkg-config",
- "output": [
- "privateFeature",
- { "type": "varAssign", "name": "QMAKE_PKG_CONFIG_HOST", "value": "tests.webengine-host-pkg-config.path" }
- ]
- },
- "webengine-gperf": {
- "label": "gperf",
- "condition": "tests.webengine-gperf",
- "output": [ "privateFeature" ]
- },
- "webengine-bison": {
- "label": "bison",
- "condition": "tests.webengine-bison",
- "output": [ "privateFeature" ]
- },
- "webengine-flex": {
- "label": "flex",
- "condition": "tests.webengine-flex",
- "output": [ "privateFeature" ]
- },
"webengine-embedded-build": {
"label": "Embedded build",
"purpose": "Enables the embedded build configuration.",
@@ -467,7 +115,7 @@
},
"webengine-alsa": {
"label": "Use ALSA",
- "condition": "config.unix && tests.webengine-alsa",
+ "condition": "config.unix && libs.webengine-alsa",
"output": [ "privateFeature" ]
},
"webengine-v8-snapshot": {
@@ -481,26 +129,6 @@
"condition": "!config.unix || !features.cross_compile || arch.arm64 || tests.webengine-host-compiler",
"output": [ "privateFeature" ]
},
- "webengine-system-khr" : {
- "label": "khr",
- "condition": "config.unix && tests.webengine-khr",
- "output": [ "privateFeature" ]
- },
- "webengine-system-libvpx" : {
- "label": "libvpx",
- "condition": "config.unix && tests.webengine-libvpx",
- "output": [ "privateFeature" ]
- },
- "webengine-system-snappy" : {
- "label": "snappy",
- "condition": "config.unix && tests.webengine-snappy",
- "output": [ "privateFeature" ]
- },
- "webengine-winversion" : {
- "label": "winversion",
- "condition": "config.win32 && tests.webengine-winversion",
- "output": [ "privateFeature" ]
- },
"webengine-geolocation": {
"label": "Geolocation",
"condition": "module.positioning",
@@ -509,7 +137,7 @@
"webengine-pulseaudio": {
"label": "Use PulseAudio",
"autoDetect": "config.unix",
- "condition": "libs.pulseaudio",
+ "condition": "libs.webengine-pulseaudio",
"output": [ "privateFeature" ]
},
"webengine-pepper-plugins": {
@@ -577,80 +205,6 @@
"autoDetect": "!features.webengine-embedded-build",
"output": [ "privateFeature" ]
},
- "webengine-system-nss": {
- "label": "nss",
- "condition": "config.unix && !config.darwin && libs.webengine-nss",
- "output": [ "privateFeature" ]
- },
- "webengine-system-libwebp": {
- "label": "libwebp, libwebpmux and libwebpdemux",
- "autoDetect": "config.unix",
- "condition": "libs.webengine-webp",
- "output": [ "privateFeature" ]
- },
- "webengine-system-opus": {
- "label": "opus",
- "autoDetect": "config.unix",
- "condition": "libs.webengine-opus",
- "output": [ "privateFeature" ]
- },
- "webengine-system-ffmpeg": {
- "label": "ffmpeg",
- "autoDetect": false,
- "condition": "libs.webengine-ffmpeg && features.webengine-system-opus && features.webengine-system-libwebp",
- "output": [ "privateFeature" ]
- },
- "webengine-system-icu": {
- "label": "icu",
- "autoDetect": false,
- "condition": "libs.webengine-icu",
- "output": [ "privateFeature" ]
- },
- "webengine-system-re2": {
- "label": "re2",
- "autoDetect": "config.unix",
- "condition": "tests.webengine-re2",
- "output": [ "privateFeature" ]
- },
- "webengine-system-ninja": {
- "label": "Use System Ninja",
- "condition": "tests.webengine-ninja",
- "output": [ "privateFeature" ]
- },
- "webengine-system-gn": {
- "label": "Use System Gn",
- "autoDetect": false,
- "condition": "tests.webengine-gn",
- "output": [ "privateFeature" ]
- },
- "webengine-system-glibc": {
- "label": "glibc",
- "condition": "config.linux && tests.webengine-glibc",
- "output": [ "privateFeature" ]
- },
- "webengine-system-libxml2": {
- "label": "libxml2 and libxslt",
- "condition": "config.unix
- && libs.webengine-libxml2
- && tests.webengine-libxml2-compatible",
- "output": [ "privateFeature" ]
- },
- "webengine-system-lcms2" : {
- "label": "lcms2",
- "autoDetect": "features.webengine-printing-and-pdf",
- "condition": "config.unix && libs.webengine-lcms2",
- "output": [ "privateFeature" ]
- },
- "webengine-system-freetype" : {
- "label": "freetype",
- "condition": "config.unix && features.system-freetype && libs.webengine-freetype",
- "output": [ "privateFeature" ]
- },
- "webengine-system-x11" : {
- "label": "x11",
- "condition": "config.unix && libs.webengine-x11",
- "output": [ "privateFeature" ]
- },
"webengine-ozone-x11" : {
"label": "Support qpa-xcb",
"condition": "config.unix
@@ -674,29 +228,11 @@
"condition": "libs.webengine-poppler-cpp",
"output": [ "privateFeature" ]
},
- "webengine-win-compiler64": {
- "label": "64bit compiler",
- "condition": "config.win32 && tests.webengine-win-compiler64",
- "output": [ "privateFeature" ]
- },
"webengine-arm-thumb": {
"label": "Thumb instruction set",
"condition": "config.linux && features.webengine-embedded-build && arch.arm && tests.webengine-arm-thumb",
"output": [ "privateFeature" ]
},
- "webengine-widgets": {
- "label": "Qt WebEngine Widgets",
- "purpose": "Provides WebEngine Widgets support.",
- "section": "WebEngine",
- "condition": "module.widgets",
- "output": [ "privateFeature" ]
- },
- "webengine-qml": {
- "label": "Qt WebEngine Qml",
- "purpose": "Provides WebEngine Qml support.",
- "section": "WebEngine",
- "output": [ "privateFeature" ]
- },
"webengine-full-debug-info": {
"label": "Full debug information",
"purpose": "Enables debug information for Blink and V8.",
@@ -717,26 +253,6 @@
"report": [
{
"type": "warning",
- "condition": "!features.webengine-python2",
- "message": "Python version 2 (2.7.5 or later) is required to build QtWebEngine."
- },
- {
- "type": "warning",
- "condition": "!features.webengine-gperf",
- "message": "gperf is required to build QtWebEngine."
- },
- {
- "type": "warning",
- "condition": "!features.webengine-bison",
- "message": "bison is required to build QtWebEngine."
- },
- {
- "type": "warning",
- "condition": "!features.webengine-flex",
- "message": "flex is required to build QtWebEngine."
- },
- {
- "type": "warning",
"condition": "config.sanitizer && !tests.webengine-sanitizer && !features.webengine-sanitizer",
"message": "Qt WebEngine cannot be built with the chosen sanitizer configuration. Check config.log for details or use -feature-webengine-sanitizer to force the build."
},
@@ -747,22 +263,21 @@
},
{
"type": "warning",
- "condition": "config.win32 && !features.webengine-win-compiler64",
- "message": "64-bit cross-building or native toolchain is required to build QtWebEngine."
+ "condition": "config.linux && features.webengine-embedded-build && !features.webengine-system-ffmpeg && arch.arm && !features.webengine-arm-thumb",
+ "message": "Thumb instruction set is required to build ffmpeg for QtWebEngine."
},
{
"type": "warning",
- "condition": "config.linux && features.webengine-embedded-build && !features.webengine-system-ffmpeg && arch.arm && !features.webengine-arm-thumb",
- "message": "Thumb instruction set is required to build ffmpeg for QtWebEngine."
+ "condition": "config.linux && features.webengine-v8-snapshot && !features.webengine-v8-snapshot-support",
+ "message": "V8 snapshot cannot be built. Most likely, the 32-bit host compiler does not work. Please make sure you have 32-bit devel environment installed."
}
],
"summary": [
{
"section": "Qt WebEngineCore",
+ "condition": "features.build-qtwebengine-core",
"entries": [
- "webengine-widgets",
- "webengine-qml",
"webengine-embedded-build",
"webengine-full-debug-info",
"webengine-pepper-plugins",
@@ -771,7 +286,6 @@
"webengine-spellchecker",
"webengine-native-spellchecker",
"webengine-webrtc",
- "webengine-system-ninja",
"webengine-geolocation",
"webengine-webchannel",
"webengine-v8-snapshot",
@@ -831,54 +345,6 @@
"type": "macosToolchainVersion",
"args": "deploymentTarget",
"condition": "config.macos"
- },
- {
- "section": "Optional system libraries used",
- "condition": "config.unix",
- "entries": [
- "webengine-system-re2",
- "webengine-system-icu",
- "webengine-system-libwebp",
- "webengine-system-opus",
- "webengine-system-ffmpeg",
- "webengine-system-libvpx",
- "webengine-system-snappy",
- "webengine-system-glib",
- "webengine-system-zlib",
- "webengine-system-minizip",
- "webengine-system-libevent",
- "webengine-system-jsoncpp",
- "webengine-system-protobuf",
- "webengine-system-libxml2",
- "webengine-system-lcms2",
- "webengine-system-png",
- "webengine-system-jpeg",
- "webengine-system-harfbuzz",
- "webengine-system-freetype"
- ]
- },
- {
- "section": "Required system libraries",
- "condition": "config.unix && !config.macos",
- "entries": [
- "webengine-system-fontconfig",
- "webengine-system-dbus",
- "webengine-system-nss",
- "webengine-system-khr",
- "webengine-system-glibc"
- ]
- },
- {
- "section": "Required system libraries for qpa-xcb",
- "condition": "config.unix && !config.macos",
- "entries": [
- "webengine-system-x11",
- "webengine-system-libdrm",
- "webengine-system-xcomposite",
- "webengine-system-xcursor",
- "webengine-system-xi",
- "webengine-system-xtst"
- ]
}
]
}
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 16945020b..5816749c8 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -87,7 +87,7 @@
#include "services/service_manager/public/cpp/service.h"
#include "services/service_manager/sandbox/switches.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
-#include "third_party/blink/public/platform/modules/insecure_input/insecure_input_service.mojom.h"
+#include "third_party/blink/public/mojom/insecure_input/insecure_input_service.mojom.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gl/gl_context.h"
@@ -195,8 +195,14 @@ public:
}
void* GetHandle() override { return m_handle; }
- // Qt currently never creates contexts using robustness attributes.
- bool WasAllocatedUsingRobustnessExtension() override { return false; }
+ bool WasAllocatedUsingRobustnessExtension() override
+ {
+#if QT_CONFIG(opengl)
+ if (QOpenGLContext *context = qt_gl_global_share_context())
+ return context->format().testOption(QSurfaceFormat::ResetNotification);
+#endif
+ return false;
+ }
// 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 { Q_UNREACHABLE(); return false; }
@@ -331,7 +337,7 @@ void ContentBrowserClientQt::OverrideWebkitPrefs(content::RenderViewHost *rvh, c
}
}
-content::QuotaPermissionContext *ContentBrowserClientQt::CreateQuotaPermissionContext()
+scoped_refptr<content::QuotaPermissionContext> ContentBrowserClientQt::CreateQuotaPermissionContext()
{
return new QuotaPermissionContextQt;
}
@@ -340,7 +346,7 @@ void ContentBrowserClientQt::GetQuotaSettings(content::BrowserContext* context,
content::StoragePartition* partition,
storage::OptionalQuotaSettingsCallback callback)
{
- storage::GetNominalDynamicSettings(partition->GetPath(), context->IsOffTheRecord(), std::move(callback));
+ storage::GetNominalDynamicSettings(partition->GetPath(), context->IsOffTheRecord(), storage::GetDefaultDiskInfoHelper(), std::move(callback));
}
// Copied from chrome/browser/ssl/ssl_error_handler.cc:
@@ -478,11 +484,12 @@ content::DevToolsManagerDelegate* ContentBrowserClientQt::GetDevToolsManagerDele
return new DevToolsManagerDelegateQt;
}
-content::PlatformNotificationService *ContentBrowserClientQt::GetPlatformNotificationService()
+content::PlatformNotificationService *ContentBrowserClientQt::GetPlatformNotificationService(content::BrowserContext *browser_context)
{
- if (!m_platformNotificationService)
- m_platformNotificationService = std::make_unique<PlatformNotificationServiceQt>();
- return m_platformNotificationService.get();
+ ProfileQt *profile = static_cast<ProfileQt *>(browser_context);
+ if (!profile)
+ return nullptr;
+ return profile->platformNotificationService();
}
// This is a really complicated way of doing absolutely nothing, but Mojo demands it:
@@ -524,7 +531,7 @@ public:
{ }
private:
- WEB_CONTENTS_USER_DATA_KEY_DECL()
+ WEB_CONTENTS_USER_DATA_KEY_DECL();
explicit ServiceDriver(content::WebContents* /*web_contents*/) { }
friend class content::WebContentsUserData<ServiceDriver>;
mojo::BindingSet<blink::mojom::InsecureInputService> m_insecureInputServiceBindings;
@@ -536,7 +543,7 @@ void ContentBrowserClientQt::InitFrameInterfaces()
{
m_frameInterfaces = std::make_unique<service_manager::BinderRegistry>();
m_frameInterfacesParameterized = std::make_unique<service_manager::BinderRegistryWithArgs<content::RenderFrameHost*>>();
- m_frameInterfacesParameterized->AddInterface(base::Bind(&ServiceDriver::BindInsecureInputService));
+ m_frameInterfacesParameterized->AddInterface(base::BindRepeating(&ServiceDriver::BindInsecureInputService));
}
void ContentBrowserClientQt::BindInterfaceRequestFromFrame(content::RenderFrameHost* render_frame_host,
@@ -741,7 +748,9 @@ bool ContentBrowserClientQt::HandleExternalProtocol(
ui::PageTransition page_transition,
bool has_user_gesture,
const std::string &method,
- const net::HttpRequestHeaders &headers)
+ const net::HttpRequestHeaders &headers,
+ network::mojom::URLLoaderFactoryRequest *factory_request,
+ network::mojom::URLLoaderFactory *&out_factory)
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
Q_UNUSED(child_id);
@@ -759,18 +768,17 @@ bool ContentBrowserClientQt::HandleExternalProtocol(
return true;
}
-scoped_refptr<content::LoginDelegate> ContentBrowserClientQt::CreateLoginDelegate(
- net::AuthChallengeInfo *authInfo,
- content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
- const content::GlobalRequestID &request_id,
+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,
+ scoped_refptr<net::HttpResponseHeaders> /*response_headers*/,
bool first_auth_attempt,
LoginAuthRequiredCallback auth_required_callback)
{
- auto loginDelegate = base::MakeRefCounted<LoginDelegateQt>(authInfo, web_contents_getter, url, first_auth_attempt, std::move(auth_required_callback));
- loginDelegate->triggerDialog();
+ auto loginDelegate = std::make_unique<LoginDelegateQt>(authInfo, web_contents, url, first_auth_attempt, std::move(auth_required_callback));
return loginDelegate;
}
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index 0b1c134cc..7f31b7c85 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -89,7 +89,7 @@ public:
void ResourceDispatcherHostCreated() override;
gl::GLShareGroup* GetInProcessGpuShareGroup() override;
content::MediaObserver* GetMediaObserver() override;
- content::QuotaPermissionContext *CreateQuotaPermissionContext() override;
+ scoped_refptr<content::QuotaPermissionContext> CreateQuotaPermissionContext() override;
void GetQuotaSettings(content::BrowserContext *context,
content::StoragePartition *partition,
storage::OptionalQuotaSettingsCallback callback) override;
@@ -108,7 +108,7 @@ public:
std::unique_ptr<content::ClientCertificateDelegate> delegate) override;
std::unique_ptr<net::ClientCertStore> CreateClientCertStore(content::ResourceContext *resource_context) override;
content::DevToolsManagerDelegate *GetDevToolsManagerDelegate() override;
- content::PlatformNotificationService *GetPlatformNotificationService() override;
+ content::PlatformNotificationService * GetPlatformNotificationService(content::BrowserContext *browser_context) override;
std::string GetApplicationLocale() override;
std::string GetAcceptLangs(content::BrowserContext* context) override;
@@ -185,11 +185,11 @@ public:
void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override;
#endif
- scoped_refptr<content::LoginDelegate> CreateLoginDelegate(
- net::AuthChallengeInfo *auth_info,
- content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
- const content::GlobalRequestID &request_id,
- bool is_main_frame,
+ 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,
@@ -203,7 +203,9 @@ public:
ui::PageTransition page_transition,
bool has_user_gesture,
const std::string &method,
- const net::HttpRequestHeaders &headers) override;
+ const net::HttpRequestHeaders &headers,
+ network::mojom::URLLoaderFactoryRequest *factory_request,
+ network::mojom::URLLoaderFactory *&out_factory) override;
static std::string getUserAgent();
@@ -216,7 +218,6 @@ private:
BrowserMainPartsQt* m_browserMainParts;
std::unique_ptr<content::ResourceDispatcherHostDelegate> m_resourceDispatcherHostDelegate;
- std::unique_ptr<content::PlatformNotificationService> m_platformNotificationService;
scoped_refptr<ShareGroupQtQuick> m_shareGroupQtQuick;
std::unique_ptr<service_manager::BinderRegistry> m_frameInterfaces;
std::unique_ptr<service_manager::BinderRegistryWithArgs<content::RenderFrameHost*>> m_frameInterfacesParameterized;
diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp
index 57f8af63c..6df20896c 100644
--- a/src/core/content_main_delegate_qt.cpp
+++ b/src/core/content_main_delegate_qt.cpp
@@ -165,6 +165,11 @@ void ContentMainDelegateQt::PreSandboxStartup()
logging::SetMinLogLevel(level);
}
}
+
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+ if (parsedCommandLine->HasSwitch(switches::kSingleProcess))
+ setlocale(LC_NUMERIC, "C");
+#endif
}
content::ContentBrowserClient *ContentMainDelegateQt::CreateContentBrowserClient()
diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri
index 8ff79c782..810ec9a0f 100644
--- a/src/core/core_chromium.pri
+++ b/src/core/core_chromium.pri
@@ -59,16 +59,21 @@ SOURCES = \
compositor/compositor_resource_tracker.cpp \
compositor/content_gpu_client_qt.cpp \
compositor/delegated_frame_node.cpp \
+ compositor/display_frame_sink.cpp \
+ compositor/display_overrides.cpp \
+ compositor/display_software_output_surface.cpp \
content_client_qt.cpp \
content_browser_client_qt.cpp \
content_main_delegate_qt.cpp \
content_utility_client_qt.cpp \
+ delegated_frame_host_client_qt.cpp \
desktop_screen_qt.cpp \
devtools_frontend_qt.cpp \
devtools_manager_delegate_qt.cpp \
download_manager_delegate_qt.cpp \
favicon_manager.cpp \
file_picker_controller.cpp \
+ find_text_helper.cpp \
javascript_dialog_controller.cpp \
javascript_dialog_manager_qt.cpp \
login_delegate_qt.cpp \
@@ -104,6 +109,7 @@ SOURCES = \
profile_io_data_qt.cpp \
quota_permission_context_qt.cpp \
quota_request_controller_impl.cpp \
+ pref_service_adapter.cpp \
register_protocol_handler_request_controller_impl.cpp \
render_view_context_menu_qt.cpp \
render_widget_host_view_qt.cpp \
@@ -162,16 +168,20 @@ HEADERS = \
compositor/compositor_resource_tracker.h \
compositor/content_gpu_client_qt.h \
compositor/delegated_frame_node.h \
+ compositor/display_frame_sink.h \
+ compositor/display_software_output_surface.h \
content_client_qt.h \
content_browser_client_qt.h \
content_main_delegate_qt.h \
content_utility_client_qt.h \
+ delegated_frame_host_client_qt.h \
desktop_screen_qt.h \
devtools_frontend_qt.h \
devtools_manager_delegate_qt.h \
download_manager_delegate_qt.h \
favicon_manager.h \
file_picker_controller.h \
+ find_text_helper.h \
global_descriptors_qt.h \
javascript_dialog_controller_p.h \
javascript_dialog_controller.h \
@@ -201,6 +211,7 @@ HEADERS = \
ozone/surface_factory_qt.h \
permission_manager_qt.h \
platform_notification_service_qt.h \
+ pref_service_adapter.h \
process_main.h \
profile_adapter.h \
profile_adapter_client.h \
@@ -244,7 +255,6 @@ HEADERS = \
web_engine_settings.h \
web_event_factory.h
-
qtConfig(webengine-ozone-x11) {
HEADERS += ozone/gl_ozone_glx_qt.h \
ozone/gl_surface_glx_qt.h
@@ -291,11 +301,13 @@ qtConfig(webengine-printing-and-pdf) {
contains(QT_CONFIG, opengl) {
SOURCES += \
compositor/compositor_resource_fence.cpp \
+ compositor/display_gl_output_surface.cpp \
+ compositor/display_gl_output_surface_qsg.cpp \
compositor/stream_video_node.cpp \
compositor/yuv_video_node.cpp
-
HEADERS += \
compositor/compositor_resource_fence.h \
+ compositor/display_gl_output_surface.h \
compositor/stream_video_node.h \
compositor/yuv_video_node.h
}
diff --git a/src/core/core_common.pri b/src/core/core_common.pri
index e548aefd1..e10d14267 100644
--- a/src/core/core_common.pri
+++ b/src/core/core_common.pri
@@ -1,5 +1,6 @@
+include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri)
include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri)
-QT_FOR_CONFIG += webenginecore webenginecore-private
+QT_FOR_CONFIG += buildtools-private webenginecore webenginecore-private
# NOTE: The TARGET, QT, QT_PRIVATE variables are used in both core_module.pro and core_gyp_generator.pro
# gyp/ninja will take care of the compilation, qmake/make will finish with linking and install.
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index b220af4a5..4b9268e1a 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -63,7 +63,7 @@ CONFIG *= no_smart_library_merge
osx {
LIBS_PRIVATE += -Wl,-force_load,$${api_library_path}$${QMAKE_DIR_SEP}lib$${api_library_name}.a
} else: win32 {
- !isDeveloperBuild() {
+ !qtConfig(webengine-developer-build) {
# Remove unused functions and data in debug non-developer builds, because the binaries will
# be smaller in the shipped packages.
QMAKE_LFLAGS += /OPT:REF
diff --git a/src/core/delegated_frame_host_client_qt.cpp b/src/core/delegated_frame_host_client_qt.cpp
new file mode 100644
index 000000000..817ea2fa5
--- /dev/null
+++ b/src/core/delegated_frame_host_client_qt.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "delegated_frame_host_client_qt.h"
+
+#include "render_widget_host_view_qt.h"
+
+namespace QtWebEngineCore {
+
+ui::Layer *DelegatedFrameHostClientQt::DelegatedFrameHostGetLayer() const
+{
+ return p->m_rootLayer.get();
+}
+
+bool DelegatedFrameHostClientQt::DelegatedFrameHostIsVisible() const
+{
+ return !p->host()->is_hidden();
+}
+
+SkColor DelegatedFrameHostClientQt::DelegatedFrameHostGetGutterColor() const
+{
+ return p->GetBackgroundColor().value_or(SK_ColorWHITE);
+}
+
+void DelegatedFrameHostClientQt::OnBeginFrame(base::TimeTicks frame_time)
+{
+ p->host()->ProgressFlingIfNeeded(frame_time);
+ p->UpdateNeedsBeginFramesInternal();
+}
+
+void DelegatedFrameHostClientQt::OnFrameTokenChanged(uint32_t frame_token)
+{
+ p->OnFrameTokenChangedForView(frame_token);
+}
+
+float DelegatedFrameHostClientQt::GetDeviceScaleFactor() const
+{
+ return p->m_screenInfo.device_scale_factor;
+}
+
+void DelegatedFrameHostClientQt::InvalidateLocalSurfaceIdOnEviction()
+{
+ p->m_dfhLocalSurfaceIdAllocator.Invalidate();
+}
+
+std::vector<viz::SurfaceId> DelegatedFrameHostClientQt::CollectSurfaceIdsForEviction()
+{
+ return p->host()->CollectSurfaceIdsForEviction();
+}
+
+bool DelegatedFrameHostClientQt::ShouldShowStaleContentOnEviction()
+{
+ return p->host()->ShouldShowStaleContentOnEviction();
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/delegated_frame_host_client_qt.h b/src/core/delegated_frame_host_client_qt.h
new file mode 100644
index 000000000..b5dc6eb59
--- /dev/null
+++ b/src/core/delegated_frame_host_client_qt.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DELEGATED_FRAME_HOST_CLIENT_QT_H
+#define DELEGATED_FRAME_HOST_CLIENT_QT_H
+
+#include "qtwebenginecoreglobal_p.h"
+
+#include "content/browser/renderer_host/delegated_frame_host.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+
+namespace QtWebEngineCore {
+
+class RenderWidgetHostViewQt;
+class DelegatedFrameHostClientQt : public content::DelegatedFrameHostClient
+{
+public:
+ explicit DelegatedFrameHostClientQt(RenderWidgetHostViewQt *p) : p(p) {}
+
+ // Overridden from content::DelegatedFrameHostClient
+ ui::Layer *DelegatedFrameHostGetLayer() const override;
+ bool DelegatedFrameHostIsVisible() const override;
+ SkColor DelegatedFrameHostGetGutterColor() const override;
+ void OnBeginFrame(base::TimeTicks frame_time) override;
+ void OnFrameTokenChanged(uint32_t frame_token) override;
+ float GetDeviceScaleFactor() const override;
+ void InvalidateLocalSurfaceIdOnEviction() override;
+ std::vector<viz::SurfaceId> CollectSurfaceIdsForEviction() override;
+ bool ShouldShowStaleContentOnEviction() override;
+
+private:
+ RenderWidgetHostViewQt *p;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // !DELEGATED_FRAME_HOST_CLIENT_QT_H
diff --git a/src/core/devtools_frontend_qt.cpp b/src/core/devtools_frontend_qt.cpp
index 28af84bd3..d3f46f648 100644
--- a/src/core/devtools_frontend_qt.cpp
+++ b/src/core/devtools_frontend_qt.cpp
@@ -189,6 +189,8 @@ DevToolsFrontendQt *DevToolsFrontendQt::Show(QSharedPointer<WebContentsAdapter>
frontendAdapter->initialize(site.get());
}
+ frontendAdapter->setInspector(true);
+
content::WebContents *contents = frontendAdapter->webContents();
if (contents == inspectedContents) {
LOG(WARNING) << "You can not inspect yourself";
@@ -231,6 +233,8 @@ DevToolsFrontendQt::DevToolsFrontendQt(QSharedPointer<WebContentsAdapter> webCon
DevToolsFrontendQt::~DevToolsFrontendQt()
{
+ if (QSharedPointer<WebContentsAdapter> p = m_webContentsAdapter)
+ p->setInspector(false);
}
void DevToolsFrontendQt::Activate()
@@ -358,7 +362,7 @@ void DevToolsFrontendQt::HandleMessageFromDevToolsFrontend(const std::string &me
std::string method;
base::ListValue *params = nullptr;
base::DictionaryValue *dict = nullptr;
- std::unique_ptr<base::Value> parsed_message = base::JSONReader::Read(message);
+ std::unique_ptr<base::Value> parsed_message = base::JSONReader::ReadDeprecated(message);
if (!parsed_message || !parsed_message->GetAsDictionary(&dict) || !dict->GetString("method", &method))
return;
int request_id = 0;
@@ -371,7 +375,8 @@ void DevToolsFrontendQt::HandleMessageFromDevToolsFrontend(const std::string &me
return;
m_agentHost->DispatchProtocolMessage(this, protocol_message);
} else if (method == "loadCompleted") {
- web_contents()->GetMainFrame()->ExecuteJavaScript(base::ASCIIToUTF16("DevToolsAPI.setUseSoftMenu(true);"));
+ web_contents()->GetMainFrame()->ExecuteJavaScript(base::ASCIIToUTF16("DevToolsAPI.setUseSoftMenu(true);"),
+ base::NullCallback());
} else if (method == "loadNetworkResource" && params->GetSize() == 3) {
// TODO(pfeldman): handle some of the embedder messages in content.
std::string url;
@@ -449,7 +454,8 @@ void DevToolsFrontendQt::HandleMessageFromDevToolsFrontend(const std::string &me
} else if (method == "clearPreferences") {
ClearPreferences();
} else if (method == "requestFileSystems") {
- web_contents()->GetMainFrame()->ExecuteJavaScript(base::ASCIIToUTF16("DevToolsAPI.fileSystemsLoaded([]);"));
+ web_contents()->GetMainFrame()->ExecuteJavaScript(base::ASCIIToUTF16("DevToolsAPI.fileSystemsLoaded([]);"),
+ base::NullCallback());
} else if (method == "reattach") {
m_agentHost->DetachClient(this);
m_agentHost->AttachClient(this);
@@ -494,7 +500,7 @@ void DevToolsFrontendQt::DispatchProtocolMessage(content::DevToolsAgentHost *age
base::EscapeJSONString(message, true, &param);
std::string code = "DevToolsAPI.dispatchMessage(" + param + ");";
base::string16 javascript = base::UTF8ToUTF16(code);
- web_contents()->GetMainFrame()->ExecuteJavaScript(javascript);
+ web_contents()->GetMainFrame()->ExecuteJavaScript(javascript, base::NullCallback());
return;
}
@@ -505,7 +511,7 @@ void DevToolsFrontendQt::DispatchProtocolMessage(content::DevToolsAgentHost *age
std::string code = "DevToolsAPI.dispatchMessageChunk(" + param + ","
+ std::to_string(pos ? 0 : total_size) + ");";
base::string16 javascript = base::UTF8ToUTF16(code);
- web_contents()->GetMainFrame()->ExecuteJavaScript(javascript);
+ web_contents()->GetMainFrame()->ExecuteJavaScript(javascript, base::NullCallback());
}
}
@@ -529,7 +535,7 @@ void DevToolsFrontendQt::CallClientFunction(const std::string &function_name,
}
}
javascript.append(");");
- web_contents()->GetMainFrame()->ExecuteJavaScript(base::UTF8ToUTF16(javascript));
+ web_contents()->GetMainFrame()->ExecuteJavaScript(base::UTF8ToUTF16(javascript), base::NullCallback());
}
void DevToolsFrontendQt::SendMessageAck(int request_id, const base::Value *arg)
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index 2af958068..34e290317 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -168,22 +168,7 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem*
QDir defaultDownloadDirectory(m_profileAdapter->downloadPath());
- QFileInfo suggestedFile(defaultDownloadDirectory.absoluteFilePath(suggestedFilename));
- QString suggestedFilePath = suggestedFile.absoluteFilePath();
- base::FilePath tmpFilePath(toFilePath(suggestedFilePath).NormalizePathSeparatorsTo('/'));
-
- int uniquifier = base::GetUniquePathNumber(tmpFilePath, base::FilePath::StringType());
- if (uniquifier > 0)
- suggestedFilePath = toQt(tmpFilePath.InsertBeforeExtensionASCII(base::StringPrintf(" (%d)", uniquifier)).AsUTF8Unsafe());
- else if (uniquifier == -1) {
- base::Time::Exploded exploded;
- item->GetStartTime().LocalExplode(&exploded);
- std::string suffix = base::StringPrintf(
- " - %04d-%02d-%02dT%02d%02d%02d.%03d", exploded.year, exploded.month,
- exploded.day_of_month, exploded.hour, exploded.minute,
- exploded.second, exploded.millisecond);
- suggestedFilePath = toQt(tmpFilePath.InsertBeforeExtensionASCII(suffix).AsUTF8Unsafe());
- }
+ QString suggestedFilePath = m_profileAdapter->determineDownloadPath(defaultDownloadDirectory.absolutePath(), suggestedFilename, item->GetStartTime().ToTimeT());
item->AddObserver(this);
QList<ProfileAdapterClient*> clients = m_profileAdapter->clients();
@@ -208,7 +193,9 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem*
false /* done */,
downloadType,
item->GetLastReason(),
- adapterClient
+ adapterClient,
+ suggestedFilename,
+ item->GetStartTime().ToTimeT()
};
for (ProfileAdapterClient *client : qAsConst(clients)) {
@@ -217,7 +204,7 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem*
break;
}
- suggestedFile.setFile(info.path);
+ QFileInfo suggestedFile(info.path);
if (info.accepted && !suggestedFile.absoluteDir().mkpath(suggestedFile.absolutePath())) {
qWarning("Creating download path failed, download cancelled: %s", suggestedFile.absolutePath().toUtf8().data());
@@ -278,7 +265,7 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content
acceptedByDefault = true;
}
if (QFileInfo(suggestedFilePath).isRelative()) {
- const QDir downloadDir(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
+ const QDir downloadDir(m_profileAdapter->downloadPath());
suggestedFilePath = downloadDir.absoluteFilePath(suggestedFilePath);
}
@@ -309,7 +296,9 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content
false, /* done */
ProfileAdapterClient::SavePage,
ProfileAdapterClient::NoReason,
- adapterClient
+ adapterClient,
+ QFileInfo(suggestedFilePath).fileName(),
+ time_t(QDateTime::currentMSecsSinceEpoch())
};
for (ProfileAdapterClient *client : qAsConst(clients)) {
@@ -375,7 +364,9 @@ void DownloadManagerDelegateQt::OnDownloadUpdated(download::DownloadItem *downlo
download->IsDone(),
0 /* downloadType (unused) */,
download->GetLastReason(),
- adapterClient
+ adapterClient,
+ toQt(download->GetSuggestedFilename()),
+ download->GetStartTime().ToTimeT()
};
for (ProfileAdapterClient *client : qAsConst(clients)) {
diff --git a/src/core/download_manager_delegate_qt.h b/src/core/download_manager_delegate_qt.h
index 382c57524..6acfa42ce 100644
--- a/src/core/download_manager_delegate_qt.h
+++ b/src/core/download_manager_delegate_qt.h
@@ -109,6 +109,7 @@ private:
bool m_nextDownloadIsUserRequested;
friend class DownloadManagerDelegateInstance;
+ friend class ProfileAdapter;
DISALLOW_COPY_AND_ASSIGN(DownloadManagerDelegateQt);
};
diff --git a/src/core/extensions/component_extension_resource_manager_qt.cpp b/src/core/extensions/component_extension_resource_manager_qt.cpp
index 57e35c231..09311c764 100644
--- a/src/core/extensions/component_extension_resource_manager_qt.cpp
+++ b/src/core/extensions/component_extension_resource_manager_qt.cpp
@@ -60,7 +60,7 @@ ComponentExtensionResourceManagerQt::~ComponentExtensionResourceManagerQt() {}
bool ComponentExtensionResourceManagerQt::IsComponentExtensionResource(const base::FilePath &extension_path,
const base::FilePath &resource_path,
- int *resource_id) const
+ ComponentExtensionResourceInfo* resource_info) const
{
base::FilePath directory_path = extension_path;
base::FilePath resources_dir;
@@ -73,11 +73,13 @@ bool ComponentExtensionResourceManagerQt::IsComponentExtensionResource(const bas
relative_path = relative_path.Append(resource_path);
relative_path = relative_path.NormalizePathSeparators();
- std::map<base::FilePath, int>::const_iterator entry = path_to_resource_id_.find(relative_path);
- if (entry != path_to_resource_id_.end())
- *resource_id = entry->second;
+ auto entry = path_to_resource_info_.find(relative_path);
+ if (entry != path_to_resource_info_.end()) {
+ *resource_info = entry->second;
+ return true;
+ }
- return entry != path_to_resource_id_.end();
+ return false;
}
const ui::TemplateReplacements *ComponentExtensionResourceManagerQt::GetTemplateReplacementsForExtension(const std::string &) const
@@ -85,14 +87,15 @@ const ui::TemplateReplacements *ComponentExtensionResourceManagerQt::GetTemplate
return nullptr;
}
-void ComponentExtensionResourceManagerQt::AddComponentResourceEntries(const GritResourceMap *entries, size_t size)
+void ComponentExtensionResourceManagerQt::AddComponentResourceEntries(const GzippedGritResourceMap *entries, size_t size)
{
for (size_t i = 0; i < size; ++i) {
base::FilePath resource_path = base::FilePath().AppendASCII(entries[i].name);
resource_path = resource_path.NormalizePathSeparators();
- DCHECK(path_to_resource_id_.find(resource_path) == path_to_resource_id_.end());
- path_to_resource_id_[resource_path] = entries[i].value;
+ DCHECK(!base::ContainsKey(path_to_resource_info_, resource_path));
+ path_to_resource_info_[resource_path] = { entries[i].value,
+ entries[i].gzipped };
}
}
diff --git a/src/core/extensions/component_extension_resource_manager_qt.h b/src/core/extensions/component_extension_resource_manager_qt.h
index 2d858630f..c44c23439 100644
--- a/src/core/extensions/component_extension_resource_manager_qt.h
+++ b/src/core/extensions/component_extension_resource_manager_qt.h
@@ -49,7 +49,7 @@
#include "base/files/file_path.h"
#include "extensions/browser/component_extension_resource_manager.h"
-struct GritResourceMap;
+struct GzippedGritResourceMap;
namespace extensions {
@@ -62,15 +62,15 @@ public:
// Overridden from ComponentExtensionResourceManager:
bool IsComponentExtensionResource(const base::FilePath &extension_path,
const base::FilePath &resource_path,
- int *resource_id) const override;
+ ComponentExtensionResourceInfo *resource_info) const override;
const ui::TemplateReplacements *GetTemplateReplacementsForExtension(const std::string& extension_id) const override;
private:
- void AddComponentResourceEntries(const GritResourceMap* entries, size_t size);
+ void AddComponentResourceEntries(const GzippedGritResourceMap* entries, size_t size);
// A map from a resource path to the resource ID. Used by
// IsComponentExtensionResource.
- std::map<base::FilePath, int> path_to_resource_id_;
+ std::map<base::FilePath, ComponentExtensionResourceInfo> path_to_resource_info_;
DISALLOW_COPY_AND_ASSIGN(ComponentExtensionResourceManagerQt);
};
diff --git a/src/core/extensions/extension_system_qt.h b/src/core/extensions/extension_system_qt.h
index 0ebe1d044..712e0104d 100644
--- a/src/core/extensions/extension_system_qt.h
+++ b/src/core/extensions/extension_system_qt.h
@@ -49,12 +49,12 @@
#include <string>
+#include "base/one_shot_event.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "build/build_config.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension_set.h"
-#include "extensions/common/one_shot_event.h"
namespace extensions {
@@ -120,7 +120,7 @@ public:
void Init(bool extensions_enabled);
- const OneShotEvent &ready() const override { return ready_; }
+ const base::OneShotEvent &ready() const override { return ready_; }
private:
void OnExtensionRegisteredWithRequestContexts(scoped_refptr<const extensions::Extension> extension);
@@ -141,7 +141,7 @@ private:
// For verifying the contents of extensions read from disk.
scoped_refptr<ContentVerifier> content_verifier_;
- OneShotEvent ready_;
+ base::OneShotEvent ready_;
content::BrowserContext *browser_context_;
scoped_refptr<ValueStoreFactory> store_factory_;
diff --git a/src/core/extensions/extension_web_contents_observer_qt.h b/src/core/extensions/extension_web_contents_observer_qt.h
index 267a1095c..5f32562fc 100644
--- a/src/core/extensions/extension_web_contents_observer_qt.h
+++ b/src/core/extensions/extension_web_contents_observer_qt.h
@@ -67,7 +67,7 @@ public:
private:
friend class content::WebContentsUserData<ExtensionWebContentsObserverQt>;
- WEB_CONTENTS_USER_DATA_KEY_DECL()
+ WEB_CONTENTS_USER_DATA_KEY_DECL();
DISALLOW_COPY_AND_ASSIGN(ExtensionWebContentsObserverQt);
};
diff --git a/src/core/extensions/extensions_browser_client_qt.cpp b/src/core/extensions/extensions_browser_client_qt.cpp
index 8bba4128f..fc1def3ca 100644
--- a/src/core/extensions/extensions_browser_client_qt.cpp
+++ b/src/core/extensions/extensions_browser_client_qt.cpp
@@ -69,6 +69,7 @@
#include "net/base/completion_once_callback.h"
#include "net/base/mime_util.h"
#include "net/url_request/url_request_simple_job.h"
+#include "services/network/public/mojom/url_loader.mojom.h"
#include "ui/base/resource/resource_bundle.h"
#include "component_extension_resource_manager_qt.h"
@@ -108,12 +109,12 @@ public:
URLRequestResourceBundleJob(net::URLRequest *request,
net::NetworkDelegate *network_delegate,
const base::FilePath &filename,
- int resource_id,
+ const extensions::ComponentExtensionResourceInfo &resource_info,
const std::string &content_security_policy,
bool send_cors_header)
: net::URLRequestSimpleJob(request, network_delegate)
, filename_(filename)
- , resource_id_(resource_id)
+ , resource_info_(resource_info)
, weak_factory_(this)
{
// Leave cache headers out of resource bundle requests.
@@ -125,7 +126,7 @@ public:
net::CompletionOnceCallback callback) const override
{
const ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- *data = rb.LoadDataResourceBytes(resource_id_);
+ *data = rb.LoadDataResourceBytes(resource_info_.resource_id);
// Add the Content-Length header now that we know the resource length.
response_info_.headers->AddHeader(
@@ -171,8 +172,8 @@ private:
// We need the filename of the resource to determine the mime type.
base::FilePath filename_;
- // The resource bundle id to load.
- int resource_id_;
+ // The resource to load.
+ const extensions::ComponentExtensionResourceInfo resource_info_;
net::HttpResponseInfo response_info_;
@@ -266,14 +267,14 @@ net::URLRequestJob *ExtensionsBrowserClientQt::MaybeCreateResourceBundleRequestJ
// extension relative path against resources_path.
resources_path.AppendRelativePath(directory_path, &relative_path)) {
base::FilePath request_path = extensions::file_util::ExtensionURLToRelativeFilePath(request->url());
- int resource_id = 0;
- if (GetComponentExtensionResourceManager()->IsComponentExtensionResource(directory_path, request_path, &resource_id)) {
+ ComponentExtensionResourceInfo resource_info;
+ if (GetComponentExtensionResourceManager()->IsComponentExtensionResource(directory_path, request_path, &resource_info)) {
relative_path = relative_path.Append(request_path);
relative_path = relative_path.NormalizePathSeparators();
return new URLRequestResourceBundleJob(request,
network_delegate,
relative_path,
- resource_id,
+ resource_info,
content_security_policy,
send_cors_header);
}
@@ -284,9 +285,9 @@ net::URLRequestJob *ExtensionsBrowserClientQt::MaybeCreateResourceBundleRequestJ
// Return the resource relative path and id for the given request.
base::FilePath ExtensionsBrowserClientQt::GetBundleResourcePath(const network::ResourceRequest &request,
const base::FilePath &extension_resources_path,
- int *resource_id) const
+ ComponentExtensionResourceInfo *resource_info) const
{
- *resource_id = 0;
+ *resource_info = {};
// |chrome_resources_path| corresponds to src/chrome/browser/resources in
// source tree.
base::FilePath resources_path;
@@ -303,10 +304,10 @@ base::FilePath ExtensionsBrowserClientQt::GetBundleResourcePath(const network::R
const base::FilePath request_relative_path =
extensions::file_util::ExtensionURLToRelativeFilePath(request.url);
if (!ExtensionsBrowserClient::Get()->GetComponentExtensionResourceManager()->IsComponentExtensionResource(
- extension_resources_path, request_relative_path, resource_id)) {
+ extension_resources_path, request_relative_path, resource_info)) {
return base::FilePath();
}
- DCHECK_NE(0, *resource_id);
+ DCHECK_NE(0, resource_info->resource_id);
return request_relative_path;
}
@@ -316,7 +317,7 @@ base::FilePath ExtensionsBrowserClientQt::GetBundleResourcePath(const network::R
void ExtensionsBrowserClientQt::LoadResourceFromResourceBundle(const network::ResourceRequest &request,
network::mojom::URLLoaderRequest loader,
const base::FilePath &resource_relative_path,
- int resource_id,
+ const ComponentExtensionResourceInfo &resource_info,
const std::string &content_security_policy,
network::mojom::URLLoaderClientPtr client,
bool send_cors_header)
diff --git a/src/core/extensions/extensions_browser_client_qt.h b/src/core/extensions/extensions_browser_client_qt.h
index f766b96a7..aa478461f 100644
--- a/src/core/extensions/extensions_browser_client_qt.h
+++ b/src/core/extensions/extensions_browser_client_qt.h
@@ -124,14 +124,14 @@ public:
// Return the resource relative path and id for the given request.
base::FilePath GetBundleResourcePath(const network::ResourceRequest &request,
const base::FilePath &extension_resources_path,
- int *resource_id) const override;
+ ComponentExtensionResourceInfo *resource_info) const override;
// Creates and starts a URLLoader to load an extension resource from the
// embedder's resource bundle (.pak) files. Used for component extensions.
void LoadResourceFromResourceBundle(const network::ResourceRequest &request,
network::mojom::URLLoaderRequest loader,
const base::FilePath &resource_relative_path,
- int resource_id,
+ const ComponentExtensionResourceInfo& resource_info,
const std::string &content_security_policy,
network::mojom::URLLoaderClientPtr client,
bool send_cors_header) override;
diff --git a/src/core/favicon_manager.cpp b/src/core/favicon_manager.cpp
index f7ba858c1..a06da6769 100644
--- a/src/core/favicon_manager.cpp
+++ b/src/core/favicon_manager.cpp
@@ -229,11 +229,10 @@ QList<FaviconInfo> FaviconManager::getFaviconInfoList(bool candidatesOnly) const
QList<FaviconInfo> faviconInfoList = m_faviconInfoMap.values();
if (candidatesOnly) {
- QMutableListIterator<FaviconInfo> it(faviconInfoList);
- while (it.hasNext()) {
- if (!it.next().candidate)
- it.remove();
- }
+ const auto hasNoCandidate = [](const FaviconInfo &info) { return !info.candidate; };
+ faviconInfoList.erase(std::remove_if(faviconInfoList.begin(), faviconInfoList.end(),
+ hasNoCandidate),
+ faviconInfoList.end());
}
return faviconInfoList;
@@ -362,6 +361,11 @@ void FaviconManager::generateCandidateIcon(bool touchIconsEnabled)
}
}
+void FaviconManager::copyStateFrom(FaviconManager *source)
+{
+ m_faviconInfoMap = source->m_faviconInfoMap;
+ m_icons = source->m_icons;
+}
FaviconInfo::FaviconInfo()
: url(QUrl())
diff --git a/src/core/favicon_manager.h b/src/core/favicon_manager.h
index 75d6aa75b..a8247d15f 100644
--- a/src/core/favicon_manager.h
+++ b/src/core/favicon_manager.h
@@ -90,7 +90,7 @@ public:
TouchIcon = 1 << 1,
TouchPrecomposedIcon = 1 << 2
};
- Q_DECLARE_FLAGS(FaviconTypeFlags, FaviconTypeFlag);
+ Q_DECLARE_FLAGS(FaviconTypeFlags, FaviconTypeFlag)
FaviconInfo();
FaviconInfo(const FaviconInfo &);
@@ -118,6 +118,7 @@ public:
QIcon getIcon(const QUrl &url = QUrl()) const;
FaviconInfo getFaviconInfo(const QUrl &) const;
QList<FaviconInfo> getFaviconInfoList(bool) const;
+ void copyStateFrom(FaviconManager *source);
private:
void update(const QList<FaviconInfo> &);
diff --git a/src/core/find_text_helper.cpp b/src/core/find_text_helper.cpp
new file mode 100644
index 000000000..effda529f
--- /dev/null
+++ b/src/core/find_text_helper.cpp
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "find_text_helper.h"
+#include "qwebenginefindtextresult.h"
+#include "type_conversion.h"
+#include "web_contents_adapter_client.h"
+
+#include "content/public/browser/web_contents.h"
+#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h"
+
+namespace QtWebEngineCore {
+
+// static
+int FindTextHelper::m_findRequestIdCounter = -1;
+
+FindTextHelper::FindTextHelper(content::WebContents *webContents, WebContentsAdapterClient *viewClient)
+ : m_webContents(webContents)
+ , m_viewClient(viewClient)
+ , m_currentFindRequestId(m_findRequestIdCounter++)
+ , m_lastCompletedFindRequestId(m_currentFindRequestId)
+{
+}
+
+FindTextHelper::~FindTextHelper()
+{
+ if (isFindTextInProgress())
+ stopFinding();
+}
+
+void FindTextHelper::startFinding(const QString &findText, bool caseSensitively, bool findBackward, const QWebEngineCallback<bool> resultCallback)
+{
+ if (findText.isEmpty()) {
+ stopFinding();
+ m_viewClient->findTextFinished(QWebEngineFindTextResult());
+ m_widgetCallbacks.invokeEmpty(resultCallback);
+ return;
+ }
+
+ startFinding(findText, caseSensitively, findBackward);
+ m_widgetCallbacks.registerCallback(m_currentFindRequestId, resultCallback);
+}
+
+void FindTextHelper::startFinding(const QString &findText, bool caseSensitively, bool findBackward, const QJSValue &resultCallback)
+{
+ if (findText.isEmpty()) {
+ stopFinding();
+ m_viewClient->findTextFinished(QWebEngineFindTextResult());
+ if (!resultCallback.isUndefined()) {
+ QJSValueList args;
+ args.append(QJSValue(0));
+ const_cast<QJSValue&>(resultCallback).call(args);
+ }
+ return;
+ }
+
+ startFinding(findText, caseSensitively, findBackward);
+ if (!resultCallback.isUndefined())
+ m_quickCallbacks.insert(m_currentFindRequestId, resultCallback);
+}
+
+void FindTextHelper::startFinding(const QString &findText, bool caseSensitively, bool findBackward)
+{
+ if (findText.isEmpty()) {
+ stopFinding();
+ return;
+ }
+
+ if (m_currentFindRequestId > m_lastCompletedFindRequestId) {
+ // There are cases where the render process will overwrite a previous request
+ // with the new search and we'll have a dangling callback, leaving the application
+ // waiting for it forever.
+ // Assume that any unfinished find has been unsuccessful when a new one is started
+ // to cover that case.
+ m_viewClient->findTextFinished(QWebEngineFindTextResult());
+ invokeResultCallback(m_currentFindRequestId, 0);
+ }
+
+ blink::mojom::FindOptionsPtr options = blink::mojom::FindOptions::New();
+ options->forward = !findBackward;
+ options->match_case = caseSensitively;
+ options->find_next = findText == m_previousFindText;
+ m_previousFindText = findText;
+
+ m_currentFindRequestId = m_findRequestIdCounter++;
+ m_webContents->Find(m_currentFindRequestId, toString16(findText), std::move(options));
+}
+
+void FindTextHelper::stopFinding()
+{
+ m_lastCompletedFindRequestId = m_currentFindRequestId;
+ m_previousFindText = QString();
+ m_webContents->StopFinding(content::STOP_FIND_ACTION_KEEP_SELECTION);
+}
+
+bool FindTextHelper::isFindTextInProgress() const
+{
+ return m_currentFindRequestId != m_lastCompletedFindRequestId;
+}
+
+void FindTextHelper::handleFindReply(content::WebContents *source, int requestId, int numberOfMatches,
+ const gfx::Rect &selectionRect, int activeMatchOrdinal, bool finalUpdate)
+{
+ Q_UNUSED(selectionRect);
+
+ Q_ASSERT(source == m_webContents);
+
+ if (!finalUpdate || requestId <= m_lastCompletedFindRequestId)
+ return;
+
+ Q_ASSERT(m_currentFindRequestId == requestId);
+ m_lastCompletedFindRequestId = requestId;
+ m_viewClient->findTextFinished(QWebEngineFindTextResult(numberOfMatches, activeMatchOrdinal));
+ invokeResultCallback(requestId, numberOfMatches);
+}
+
+void FindTextHelper::handleLoadCommitted()
+{
+ // Make sure that we don't set the findNext WebFindOptions on a new frame.
+ m_previousFindText = QString();
+}
+
+void FindTextHelper::invokeResultCallback(int requestId, int numberOfMatches)
+{
+ if (m_quickCallbacks.contains(requestId)) {
+ QJSValue resultCallback = m_quickCallbacks.take(requestId);
+ QJSValueList args;
+ args.append(QJSValue(numberOfMatches));
+ resultCallback.call(args);
+ } else {
+ m_widgetCallbacks.invoke(requestId, numberOfMatches > 0);
+ }
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/find_text_helper.h b/src/core/find_text_helper.h
new file mode 100644
index 000000000..e8f186272
--- /dev/null
+++ b/src/core/find_text_helper.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// 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.
+//
+
+#ifndef FIND_TEXT_HELPER_H
+#define FIND_TEXT_HELPER_H
+
+#include "qtwebenginecoreglobal_p.h"
+
+#include "qwebenginecallback_p.h"
+#include <QJSValue>
+
+namespace content {
+class WebContents;
+}
+
+namespace gfx {
+class Rect;
+}
+
+namespace QtWebEngineCore {
+
+class WebContentsAdapterClient;
+
+class Q_WEBENGINECORE_PRIVATE_EXPORT FindTextHelper {
+public:
+ FindTextHelper(content::WebContents *webContents, WebContentsAdapterClient *viewClient);
+ ~FindTextHelper();
+
+ void startFinding(const QString &findText, bool caseSensitively, bool findBackward, const QWebEngineCallback<bool> resultCallback);
+ void startFinding(const QString &findText, bool caseSensitively, bool findBackward, const QJSValue &resultCallback);
+ void startFinding(const QString &findText, bool caseSensitively, bool findBackward);
+ void stopFinding();
+ bool isFindTextInProgress() const;
+ void handleFindReply(content::WebContents *source, int requestId, int numberOfMatches, const gfx::Rect &selectionRect, int activeMatchOrdinal, bool finalUpdate);
+ void handleLoadCommitted();
+
+private:
+ void invokeResultCallback(int requestId, int numberOfMatches);
+
+ content::WebContents *m_webContents;
+ WebContentsAdapterClient *m_viewClient;
+
+ static int m_findRequestIdCounter;
+ int m_currentFindRequestId;
+ int m_lastCompletedFindRequestId;
+
+ QString m_previousFindText;
+
+ QMap<int, QJSValue> m_quickCallbacks;
+ CallbackDirectory m_widgetCallbacks;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // FIND_TEXT_HELPER_H
diff --git a/src/core/gn_run.pro b/src/core/gn_run.pro
index 0219a2be9..377d8363c 100644
--- a/src/core/gn_run.pro
+++ b/src/core/gn_run.pro
@@ -1,5 +1,6 @@
+include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri)
include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri)
-QT_FOR_CONFIG += webenginecore-private
+QT_FOR_CONFIG += buildtools-private webenginecore-private core-private gui-private
TEMPLATE = aux
diff --git a/src/core/login_delegate_qt.cpp b/src/core/login_delegate_qt.cpp
index 0050f87c7..7970b9b46 100644
--- a/src/core/login_delegate_qt.cpp
+++ b/src/core/login_delegate_qt.cpp
@@ -72,36 +72,25 @@
namespace QtWebEngineCore {
-LoginDelegateQt::LoginDelegateQt(
- net::AuthChallengeInfo *authInfo,
- content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
- GURL url,
- bool first_auth_attempt,
- LoginAuthRequiredCallback auth_required_callback)
- : m_authInfo(authInfo)
+LoginDelegateQt::LoginDelegateQt(const net::AuthChallengeInfo &authInfo,
+ content::WebContents *web_contents,
+ GURL url,
+ bool /*first_auth_attempt*/,
+ LoginAuthRequiredCallback auth_required_callback)
+ : content::WebContentsObserver(web_contents)
+ , m_authInfo(authInfo)
, m_url(url)
, m_auth_required_callback(std::move(auth_required_callback))
- , m_webContentsGetter(web_contents_getter)
-{
- Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
-}
-
-LoginDelegateQt::~LoginDelegateQt()
-{
- Q_ASSERT(m_dialogController.isNull());
-}
-
-void LoginDelegateQt::triggerDialog()
+ , m_weakFactory(this)
{
base::PostTaskWithTraits(
FROM_HERE, { content::BrowserThread::UI },
- base::BindOnce(&LoginDelegateQt::triggerDialogOnUI, this));
+ base::BindOnce(&LoginDelegateQt::triggerDialog, m_weakFactory.GetWeakPtr()));
}
-void LoginDelegateQt::OnRequestCancelled()
+LoginDelegateQt::~LoginDelegateQt()
{
destroy();
- // TODO: this should close native dialog, since page can be navigated somewhere else
}
QUrl LoginDelegateQt::url() const
@@ -111,57 +100,55 @@ QUrl LoginDelegateQt::url() const
QString LoginDelegateQt::realm() const
{
- return QString::fromStdString(m_authInfo->realm);
+ return QString::fromStdString(m_authInfo.realm);
}
QString LoginDelegateQt::host() const
{
- return QString::fromStdString(m_authInfo->challenger.host());
+ return QString::fromStdString(m_authInfo.challenger.host());
}
int LoginDelegateQt::port() const
{
- return m_authInfo->challenger.port();
+ return m_authInfo.challenger.port();
}
bool LoginDelegateQt::isProxy() const
{
- return m_authInfo->is_proxy;
+ return m_authInfo.is_proxy;
}
-void LoginDelegateQt::triggerDialogOnUI()
+void LoginDelegateQt::triggerDialog()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (!web_contents())
+ return sendAuthToRequester(false, QString(), QString());
+
if (isProxy()) {
// workaround for 'ws' redefined symbols when including QNetworkProxy
auto authentication = WebEngineContext::qProxyNetworkAuthentication(host(), port());
- if (std::get<0>(authentication)) {
- base::PostTaskWithTraits(
- FROM_HERE, { content::BrowserThread::IO },
- base::BindOnce(&LoginDelegateQt::sendAuthToRequester, this, true,
- std::get<1>(authentication), std::get<2>(authentication)));
-
- return;
- }
+ if (std::get<0>(authentication))
+ return sendAuthToRequester(true, std::get<1>(authentication), std::get<2>(authentication));
}
- content::WebContentsImpl *webContents =
- static_cast<content::WebContentsImpl *>(m_webContentsGetter.Run());
+ content::WebContentsImpl *webContents = static_cast<content::WebContentsImpl *>(web_contents());
if (!webContents)
return;
WebContentsAdapterClient *client = WebContentsViewQt::from(webContents->GetView())->client();
- AuthenticationDialogControllerPrivate *dialogControllerData = new AuthenticationDialogControllerPrivate(this);
+ AuthenticationDialogControllerPrivate *dialogControllerData = new AuthenticationDialogControllerPrivate(m_weakFactory.GetWeakPtr());
+ dialogControllerData->url = url();
+ dialogControllerData->host = host();
+ dialogControllerData->realm = realm();
+ dialogControllerData->isProxy = isProxy();
m_dialogController.reset(new AuthenticationDialogController(dialogControllerData));
client->authenticationRequired(m_dialogController);
}
void LoginDelegateQt::sendAuthToRequester(bool success, const QString &user, const QString &password)
{
- Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
-
if (!m_auth_required_callback.is_null()) {
- if (success)
+ if (success && web_contents())
std::move(m_auth_required_callback).Run(net::AuthCredentials(toString16(user), toString16(password)));
else
std::move(m_auth_required_callback).Run(base::nullopt);
diff --git a/src/core/login_delegate_qt.h b/src/core/login_delegate_qt.h
index 3a9c073cd..20f302988 100644
--- a/src/core/login_delegate_qt.h
+++ b/src/core/login_delegate_qt.h
@@ -43,6 +43,7 @@
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/login_delegate.h"
#include "content/public/browser/resource_request_info.h"
+#include "content/public/browser/web_contents_observer.h"
#include "url/gurl.h"
#include "web_contents_adapter_client.h"
@@ -56,20 +57,17 @@ namespace QtWebEngineCore {
class AuthenticationDialogController;
-class LoginDelegateQt : public content::LoginDelegate {
+class LoginDelegateQt : public content::LoginDelegate,
+ public content::WebContentsObserver
+{
public:
- LoginDelegateQt(net::AuthChallengeInfo *authInfo,
- content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
+ LoginDelegateQt(const net::AuthChallengeInfo &authInfo,
+ content::WebContents *web_contents,
GURL url,
bool first_auth_attempt,
LoginAuthRequiredCallback auth_required_callback);
- ~LoginDelegateQt();
-
- void triggerDialog();
-
- // LoginDelegate implementation
- void OnRequestCancelled() override;
+ ~LoginDelegateQt() override;
QUrl url() const;
QString realm() const;
@@ -80,14 +78,14 @@ public:
void sendAuthToRequester(bool success, const QString &user, const QString &password);
private:
- void triggerDialogOnUI();
+ void triggerDialog();
void destroy();
- scoped_refptr<net::AuthChallengeInfo> m_authInfo;
+ net::AuthChallengeInfo m_authInfo;
GURL m_url;
LoginAuthRequiredCallback m_auth_required_callback;
- content::ResourceRequestInfo::WebContentsGetter m_webContentsGetter;
+ base::WeakPtrFactory<LoginDelegateQt> m_weakFactory;
// This member is used to keep authentication dialog controller alive until
// authorization is sent or cancelled.
diff --git a/src/core/media_capture_devices_dispatcher.cpp b/src/core/media_capture_devices_dispatcher.cpp
index ecc46f244..55c0bb39b 100644
--- a/src/core/media_capture_devices_dispatcher.cpp
+++ b/src/core/media_capture_devices_dispatcher.cpp
@@ -45,6 +45,7 @@
#include "javascript_dialog_manager_qt.h"
#include "type_conversion.h"
+#include "web_contents_delegate_qt.h"
#include "web_contents_view_qt.h"
#include "web_engine_settings.h"
@@ -166,6 +167,40 @@ WebContentsAdapterClient::MediaRequestFlags mediaRequestFlagsForRequest(const co
return requestFlags;
}
+// Based on MediaStreamCaptureIndicator::UIDelegate
+class MediaStreamUIQt : public content::MediaStreamUI
+{
+public:
+ MediaStreamUIQt(content::WebContents *webContents, const blink::MediaStreamDevices &devices)
+ : m_delegate(static_cast<WebContentsDelegateQt *>(webContents->GetDelegate())->AsWeakPtr())
+ , m_devices(devices)
+ {
+ DCHECK(!m_devices.empty());
+ }
+
+ ~MediaStreamUIQt() override
+ {
+ if (m_started && m_delegate)
+ m_delegate->removeDevices(m_devices);
+ }
+
+private:
+ gfx::NativeViewId OnStarted(base::OnceClosure, base::RepeatingClosure) override
+ {
+ DCHECK(!m_started);
+ m_started = true;
+ if (m_delegate)
+ m_delegate->addDevices(m_devices);
+ return 0;
+ }
+
+ base::WeakPtr<WebContentsDelegateQt> m_delegate;
+ const blink::MediaStreamDevices m_devices;
+ bool m_started = false;
+
+ DISALLOW_COPY_AND_ASSIGN(MediaStreamUIQt);
+};
+
} // namespace
MediaCaptureDevicesDispatcher::PendingAccessRequest::PendingAccessRequest(const content::MediaStreamRequest &request,
@@ -237,8 +272,12 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content:
base::Unretained(this), webContents));
}
- std::move(callback).Run(devices, devices.empty() ? blink::MEDIA_DEVICE_INVALID_STATE : blink::MEDIA_DEVICE_OK,
- std::unique_ptr<content::MediaStreamUI>());
+ if (devices.empty())
+ std::move(callback).Run(devices, blink::MEDIA_DEVICE_INVALID_STATE,
+ std::unique_ptr<content::MediaStreamUI>());
+ else
+ std::move(callback).Run(devices, blink::MEDIA_DEVICE_OK,
+ std::make_unique<MediaStreamUIQt>(webContents, devices));
}
MediaCaptureDevicesDispatcher *MediaCaptureDevicesDispatcher::GetInstance()
@@ -336,8 +375,12 @@ void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content::
getDevicesForDesktopCapture(&devices, mediaId, capture_audio);
- std::move(callback).Run(devices, devices.empty() ? blink::MEDIA_DEVICE_INVALID_STATE : blink::MEDIA_DEVICE_OK,
- std::unique_ptr<content::MediaStreamUI>());
+ if (devices.empty())
+ std::move(callback).Run(devices, blink::MEDIA_DEVICE_INVALID_STATE,
+ std::unique_ptr<content::MediaStreamUI>());
+ else
+ std::move(callback).Run(devices, blink::MEDIA_DEVICE_OK,
+ std::make_unique<MediaStreamUIQt>(webContents, devices));
}
void MediaCaptureDevicesDispatcher::enqueueMediaAccessRequest(content::WebContents *webContents,
diff --git a/src/core/net/client_cert_override.cpp b/src/core/net/client_cert_override.cpp
index 305f0cef0..afb7ab5af 100644
--- a/src/core/net/client_cert_override.cpp
+++ b/src/core/net/client_cert_override.cpp
@@ -78,9 +78,9 @@ public:
: net::ClientCertIdentity(std::move(cert)), m_key(std::move(key)) {}
~ClientCertIdentityOverride() override = default;
- void AcquirePrivateKey(const base::Callback<void(scoped_refptr<net::SSLPrivateKey>)> &private_key_callback) override
+ void AcquirePrivateKey(base::OnceCallback<void(scoped_refptr<net::SSLPrivateKey>)> private_key_callback) override
{
- private_key_callback.Run(m_key);
+ std::move(private_key_callback).Run(m_key);
}
#if defined(OS_MACOSX)
@@ -125,29 +125,29 @@ net::ClientCertIdentityList ClientCertOverrideStore::GetClientCertsOnUIThread(co
}
void ClientCertOverrideStore::GetClientCertsReturn(const net::SSLCertRequestInfo &cert_request_info,
- const ClientCertListCallback &callback,
+ ClientCertListCallback callback,
net::ClientCertIdentityList &&result)
{
// Continue with native cert store if matching certificatse were not found in memory
if (result.empty() && m_nativeStore)
- m_nativeStore->GetClientCerts(cert_request_info, callback);
+ m_nativeStore->GetClientCerts(cert_request_info, std::move(callback));
else
- callback.Run(std::move(result));
+ std::move(callback).Run(std::move(result));
}
#endif // QT_CONFIG(ssl)
void ClientCertOverrideStore::GetClientCerts(const net::SSLCertRequestInfo &cert_request_info,
- const ClientCertListCallback &callback)
+ ClientCertListCallback callback)
{
#if QT_CONFIG(ssl)
// Access the user-provided data from the UI thread, but return on whatever thread this is.
if (base::PostTaskWithTraitsAndReplyWithResult(
FROM_HERE, { content::BrowserThread::UI },
base::BindOnce(&ClientCertOverrideStore::GetClientCertsOnUIThread,
- base::Unretained(this), base::ConstRef(cert_request_info)),
+ base::Unretained(this), std::cref(cert_request_info)),
base::BindOnce(&ClientCertOverrideStore::GetClientCertsReturn,
- base::Unretained(this), base::ConstRef(cert_request_info), callback))
+ base::Unretained(this), std::cref(cert_request_info), std::move(callback)))
) {
return;
}
@@ -155,9 +155,9 @@ void ClientCertOverrideStore::GetClientCerts(const net::SSLCertRequestInfo &cert
// Continue with native cert store if we failed to post task
if (m_nativeStore)
- m_nativeStore->GetClientCerts(cert_request_info, callback);
+ m_nativeStore->GetClientCerts(cert_request_info, std::move(callback));
else
- callback.Run(net::ClientCertIdentityList());
+ std::move(callback).Run(net::ClientCertIdentityList());
}
// static
diff --git a/src/core/net/client_cert_override.h b/src/core/net/client_cert_override.h
index 35c1f96af..4f2734485 100644
--- a/src/core/net/client_cert_override.h
+++ b/src/core/net/client_cert_override.h
@@ -57,12 +57,12 @@ public:
ClientCertOverrideStore(ClientCertificateStoreData *storeData);
virtual ~ClientCertOverrideStore() override;
void GetClientCerts(const net::SSLCertRequestInfo &cert_request_info,
- const ClientCertListCallback &callback) override;
+ ClientCertListCallback callback) override;
private:
static std::unique_ptr<net::ClientCertStore> createNativeStore();
net::ClientCertIdentityList GetClientCertsOnUIThread(const net::SSLCertRequestInfo &request);
void GetClientCertsReturn(const net::SSLCertRequestInfo &cert_request_info,
- const ClientCertListCallback &callback,
+ ClientCertListCallback callback,
net::ClientCertIdentityList &&result);
ClientCertificateStoreData *m_storeData;
std::unique_ptr<net::ClientCertStore> m_nativeStore;
diff --git a/src/core/net/cookie_monster_delegate_qt.cpp b/src/core/net/cookie_monster_delegate_qt.cpp
index 3253b08b9..5f7b75f57 100644
--- a/src/core/net/cookie_monster_delegate_qt.cpp
+++ b/src/core/net/cookie_monster_delegate_qt.cpp
@@ -140,10 +140,29 @@ void CookieMonsterDelegateQt::deleteCookie(const QNetworkCookie &cookie, const Q
void CookieMonsterDelegateQt::DeleteCookieOnIOThread(const GURL& url, const std::string& cookie_name)
{
- if (m_cookieMonster)
- m_cookieMonster->DeleteCookieAsync(url, cookie_name, base::Closure());
+ if (m_cookieMonster) {
+ net::CookieMonster::GetCookieListCallback callback =
+ base::BindOnce(&CookieMonsterDelegateQt::GetCookiesToDeleteCallback, this, cookie_name);
+ m_cookieMonster->GetAllCookiesForURLAsync(url, std::move(callback));
+ }
}
+void CookieMonsterDelegateQt::GetCookiesToDeleteCallback(const std::string& cookie_name, const net::CookieList &cookies, const net::CookieStatusList &statusList)
+{
+ Q_UNUSED(statusList);
+ if (!m_cookieMonster)
+ return;
+
+ net::CookieList cookiesToDelete;
+ for (auto cookie : cookies) {
+ if (cookie.Name() == cookie_name)
+ cookiesToDelete.push_back(cookie);
+ }
+ for (auto cookie : cookiesToDelete)
+ m_cookieMonster->DeleteCanonicalCookieAsync(cookie, base::DoNothing());
+}
+
+
void CookieMonsterDelegateQt::deleteSessionCookies(quint64 callbackId)
{
Q_ASSERT(hasCookieMonster());
@@ -234,7 +253,7 @@ void CookieMonsterDelegateQt::OnCookieChanged(const net::CanonicalCookie& cookie
m_client->d_func()->onCookieChanged(toQt(cookie), cause != net::CookieChangeCause::INSERTED);
}
-void CookieMonsterDelegateQt::GetAllCookiesCallbackOnIOThread(qint64 callbackId, const net::CookieList &cookies)
+void CookieMonsterDelegateQt::GetAllCookiesCallbackOnIOThread(qint64 callbackId, const net::CookieList &cookies, const net::CookieStatusList &statusList)
{
QByteArray rawCookies;
for (auto &&cookie : cookies)
@@ -245,11 +264,11 @@ void CookieMonsterDelegateQt::GetAllCookiesCallbackOnIOThread(qint64 callbackId,
base::BindOnce(&CookieMonsterDelegateQt::GetAllCookiesCallbackOnUIThread, this, callbackId, rawCookies));
}
-void CookieMonsterDelegateQt::SetCookieCallbackOnIOThread(qint64 callbackId, bool success)
+void CookieMonsterDelegateQt::SetCookieCallbackOnIOThread(qint64 callbackId, net::CanonicalCookie::CookieInclusionStatus status)
{
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(&CookieMonsterDelegateQt::SetCookieCallbackOnUIThread, this, callbackId, success));
+ base::BindOnce(&CookieMonsterDelegateQt::SetCookieCallbackOnUIThread, this, callbackId, status));
}
void CookieMonsterDelegateQt::DeleteCookiesCallbackOnIOThread(qint64 callbackId, uint numCookies)
@@ -265,10 +284,11 @@ void CookieMonsterDelegateQt::GetAllCookiesCallbackOnUIThread(qint64 callbackId,
m_client->d_func()->onGetAllCallbackResult(callbackId, cookies);
}
-void CookieMonsterDelegateQt::SetCookieCallbackOnUIThread(qint64 callbackId, bool success)
+void CookieMonsterDelegateQt::SetCookieCallbackOnUIThread(qint64 callbackId, net::CanonicalCookie::CookieInclusionStatus status)
{
if (m_client)
- m_client->d_func()->onSetCallbackResult(callbackId, success);
+ m_client->d_func()->onSetCallbackResult(callbackId,
+ status == net::CanonicalCookie::CookieInclusionStatus::INCLUDE);
}
void CookieMonsterDelegateQt::DeleteCookiesCallbackOnUIThread(qint64 callbackId, uint numCookies)
diff --git a/src/core/net/cookie_monster_delegate_qt.h b/src/core/net/cookie_monster_delegate_qt.h
index 88e92b560..2ac04acb4 100644
--- a/src/core/net/cookie_monster_delegate_qt.h
+++ b/src/core/net/cookie_monster_delegate_qt.h
@@ -107,12 +107,13 @@ private:
void DeleteSessionCookiesOnIOThread(net::CookieMonster::DeleteCallback callback);
void DeleteAllOnIOThread(net::CookieMonster::DeleteCallback callback);
- void GetAllCookiesCallbackOnIOThread(qint64 callbackId, const net::CookieList &cookies);
- void SetCookieCallbackOnIOThread(qint64 callbackId, bool success);
+ void GetCookiesToDeleteCallback(const std::string& cookie_name, const net::CookieList &cookies, const net::CookieStatusList &statusList);
+ void GetAllCookiesCallbackOnIOThread(qint64 callbackId, const net::CookieList &cookies, const net::CookieStatusList &statusList);
+ void SetCookieCallbackOnIOThread(qint64 callbackId, net::CanonicalCookie::CookieInclusionStatus status);
void DeleteCookiesCallbackOnIOThread(qint64 callbackId, uint numCookies);
void GetAllCookiesCallbackOnUIThread(qint64 callbackId, const QByteArray &cookies);
- void SetCookieCallbackOnUIThread(qint64 callbackId, bool success);
+ void SetCookieCallbackOnUIThread(qint64 callbackId, net::CanonicalCookie::CookieInclusionStatus status);
void DeleteCookiesCallbackOnUIThread(qint64 callbackId, uint numCookies);
};
diff --git a/src/core/net/network_delegate_qt.cpp b/src/core/net/network_delegate_qt.cpp
index 7f278fd92..68bf34d31 100644
--- a/src/core/net/network_delegate_qt.cpp
+++ b/src/core/net/network_delegate_qt.cpp
@@ -64,13 +64,13 @@ namespace QtWebEngineCore {
WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::PageTransition transition)
{
+ if (ui::PageTransitionIsRedirect(transition))
+ return WebContentsAdapterClient::RedirectNavigation;
+
int32_t qualifier = ui::PageTransitionGetQualifier(transition);
if (qualifier & ui::PAGE_TRANSITION_FORWARD_BACK)
return WebContentsAdapterClient::BackForwardNavigation;
- // FIXME: Make redirects a separate type:
- if (qualifier & ui::PAGE_TRANSITION_CLIENT_REDIRECT)
- return WebContentsAdapterClient::OtherNavigation;
ui::PageTransition strippedTransition = ui::PageTransitionStripQualifier(transition);
@@ -90,7 +90,7 @@ WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::Page
static QWebEngineUrlRequestInfo::ResourceType toQt(content::ResourceType resourceType)
{
- if (resourceType >= 0 && resourceType < content::ResourceType(QWebEngineUrlRequestInfo::ResourceTypeLast))
+ if (resourceType >= content::ResourceType::kMainFrame && resourceType <= content::ResourceType::kMaxValue)
return static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType);
return QWebEngineUrlRequestInfo::ResourceTypeUnknown;
}
@@ -109,9 +109,9 @@ int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, net::Complet
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
Q_ASSERT(m_profileIOData);
- const content::ResourceRequestInfo *resourceInfo = content::ResourceRequestInfo::ForRequest(request);
+ content::ResourceRequestInfo *resourceInfo = content::ResourceRequestInfo::ForRequest(request);
- content::ResourceType resourceType = content::RESOURCE_TYPE_LAST_TYPE;
+ content::ResourceType resourceType = content::ResourceType::kMaxValue;
WebContentsAdapterClient::NavigationType navigationType = WebContentsAdapterClient::OtherNavigation;
if (resourceInfo) {
@@ -122,15 +122,18 @@ int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, net::Complet
const QUrl qUrl = toQt(request->url());
QUrl firstPartyUrl = QUrl();
- if (resourceType == content::ResourceType::RESOURCE_TYPE_SUB_FRAME)
+ if (resourceType == content::ResourceType::kSubFrame)
firstPartyUrl = toQt(request->first_party_url());
else
firstPartyUrl = toQt(request->site_for_cookies());
+ const QUrl initiator = request->initiator().has_value() ? toQt(request->initiator()->GetURL()) : QUrl();
+
QWebEngineUrlRequestInfoPrivate *infoPrivate = new QWebEngineUrlRequestInfoPrivate(toQt(resourceType),
toQt(navigationType),
qUrl,
firstPartyUrl,
+ initiator,
QByteArray::fromStdString(request->method()));
QWebEngineUrlRequestInfo requestInfo(infoPrivate);
diff --git a/src/core/net/url_request_custom_job.cpp b/src/core/net/url_request_custom_job.cpp
index cba9b4dc5..dd213d4f8 100644
--- a/src/core/net/url_request_custom_job.cpp
+++ b/src/core/net/url_request_custom_job.cpp
@@ -40,10 +40,13 @@
#include "url_request_custom_job.h"
#include "url_request_custom_job_proxy.h"
+#include "api/qwebengineurlscheme.h"
+#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/io_buffer.h"
+#include "net/http/http_util.h"
#include <QIODevice>
@@ -62,6 +65,9 @@ URLRequestCustomJob::URLRequestCustomJob(URLRequest *request,
, m_pendingReadSize(0)
, m_pendingReadPos(0)
, m_pendingReadBuffer(nullptr)
+ , m_corsEnabled(QWebEngineUrlScheme::schemeByName(QByteArray::fromStdString(scheme))
+ .flags().testFlag(QWebEngineUrlScheme::CorsEnabled))
+ , m_httpStatusCode(500)
{
}
@@ -136,6 +142,26 @@ bool URLRequestCustomJob::GetCharset(std::string* charset)
return false;
}
+void URLRequestCustomJob::GetResponseInfo(HttpResponseInfo* info)
+{
+ // Based on net::URLRequestRedirectJob::StartAsync()
+
+ if (!m_corsEnabled)
+ return;
+
+ std::string headers;
+ headers += base::StringPrintf("HTTP/1.1 %i OK\n", m_httpStatusCode);
+ if (m_redirect.is_valid())
+ headers += base::StringPrintf("Location: %s\n", m_redirect.spec().c_str());
+ std::string origin;
+ if (request_->extra_request_headers().GetHeader("Origin", &origin)) {
+ headers += base::StringPrintf("Access-Control-Allow-Origin: %s\n", origin.c_str());
+ headers += "Access-Control-Allow-Credentials: true\n";
+ }
+
+ info->headers = new HttpResponseHeaders(HttpUtil::AssembleRawHeaders(headers.c_str(), headers.size()));
+}
+
bool URLRequestCustomJob::IsRedirectResponse(GURL* location, int* http_status_code, bool* /*insecure_scheme_was_upgraded*/)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
diff --git a/src/core/net/url_request_custom_job.h b/src/core/net/url_request_custom_job.h
index 16be76f29..e1e8e9fba 100644
--- a/src/core/net/url_request_custom_job.h
+++ b/src/core/net/url_request_custom_job.h
@@ -64,6 +64,7 @@ public:
int ReadRawData(net::IOBuffer *buf, int buf_size) override;
bool GetMimeType(std::string *mimeType) const override;
bool GetCharset(std::string *charset) override;
+ void GetResponseInfo(net::HttpResponseInfo* info) override;
bool IsRedirectResponse(GURL* location, int* http_status_code, bool* insecure_scheme_was_upgraded) override;
protected:
@@ -80,6 +81,8 @@ private:
int m_pendingReadSize;
int m_pendingReadPos;
net::IOBuffer *m_pendingReadBuffer;
+ const bool m_corsEnabled;
+ int m_httpStatusCode;
friend class URLRequestCustomJobProxy;
diff --git a/src/core/net/url_request_custom_job_proxy.cpp b/src/core/net/url_request_custom_job_proxy.cpp
index 72d14450e..b9ccf7ea4 100644
--- a/src/core/net/url_request_custom_job_proxy.cpp
+++ b/src/core/net/url_request_custom_job_proxy.cpp
@@ -100,6 +100,7 @@ void URLRequestCustomJobProxy::reply(std::string mimeType, QIODevice *device)
m_job->set_expected_content_size(size);
if (m_job->m_device && m_job->m_device->isReadable()) {
m_started = true;
+ m_job->m_httpStatusCode = 200;
m_job->NotifyHeadersComplete();
} else {
fail(ERR_INVALID_URL);
@@ -114,6 +115,7 @@ void URLRequestCustomJobProxy::redirect(GURL url)
if (m_job->m_device || m_job->m_error)
return;
m_job->m_redirect = url;
+ m_job->m_httpStatusCode = 303;
m_started = true;
m_job->NotifyHeadersComplete();
}
@@ -138,6 +140,7 @@ void URLRequestCustomJobProxy::fail(int error)
if (!m_job)
return;
m_job->m_error = error;
+ m_job->m_httpStatusCode = 500;
if (m_job->m_device)
m_job->m_device->close();
if (!m_started)
diff --git a/src/core/net/webui_controller_factory_qt.cpp b/src/core/net/webui_controller_factory_qt.cpp
index ec36e70d9..92bb8854f 100644
--- a/src/core/net/webui_controller_factory_qt.cpp
+++ b/src/core/net/webui_controller_factory_qt.cpp
@@ -52,7 +52,6 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/devtools_ui.h"
#include "chrome/browser/ui/webui/quota_internals/quota_internals_ui.h"
-#include "chrome/browser/ui/webui/task_scheduler_internals/task_scheduler_internals_ui.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
@@ -129,8 +128,6 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI *web_ui, Profile *profile, co
// after the host name.
if (url.host() == chrome::kChromeUIQuotaInternalsHost)
return &NewWebUI<QuotaInternalsUI>;
- if (url.host_piece() == chrome::kChromeUITaskSchedulerInternalsHost)
- return &NewWebUI<TaskSchedulerInternalsUI>;
if (url.SchemeIs(content::kChromeDevToolsScheme)) {
// if (!DevToolsUIBindings::IsValidFrontendURL(url))
diff --git a/src/core/ozone/gl_context_qt.cpp b/src/core/ozone/gl_context_qt.cpp
index c4a075544..9813a3256 100644
--- a/src/core/ozone/gl_context_qt.cpp
+++ b/src/core/ozone/gl_context_qt.cpp
@@ -163,6 +163,17 @@ QFunctionPointer GLContextHelper::getEglGetProcAddress()
return get_proc_address;
}
+bool GLContextHelper::isCreateContextRobustnessSupported()
+{
+#if QT_CONFIG(opengl)
+ if (QGuiApplication::platformName() == QLatin1String("offscreen"))
+ return false;
+
+ if (QOpenGLContext *context = qt_gl_global_share_context())
+ return context->format().testOption(QSurfaceFormat::ResetNotification);
+#endif
+ return false;
+}
QT_END_NAMESPACE
#if defined(OS_WIN)
diff --git a/src/core/ozone/gl_context_qt.h b/src/core/ozone/gl_context_qt.h
index 59ee567aa..8559af313 100644
--- a/src/core/ozone/gl_context_qt.h
+++ b/src/core/ozone/gl_context_qt.h
@@ -64,6 +64,8 @@ public:
static void* getNativeDisplay();
static QFunctionPointer getGlXGetProcAddress();
static QFunctionPointer getEglGetProcAddress();
+ static bool isCreateContextRobustnessSupported();
+
private:
Q_INVOKABLE bool initializeContextOnBrowserThread(gl::GLContext* context, gl::GLSurface* surface, gl::GLContextAttribs attribs);
diff --git a/src/core/ozone/gl_ozone_glx_qt.cpp b/src/core/ozone/gl_ozone_glx_qt.cpp
index e3a4f4708..f934a5c80 100644
--- a/src/core/ozone/gl_ozone_glx_qt.cpp
+++ b/src/core/ozone/gl_ozone_glx_qt.cpp
@@ -111,8 +111,10 @@ void GLOzoneGLXQt::ShutdownGL() {
}
bool GLOzoneGLXQt::GetGLWindowSystemBindingInfo(
- gl::GLWindowSystemBindingInfo* info) {
- return gl::GetGLWindowSystemBindingInfoGLX(info);
+ const gl::GLVersionInfo &gl_info,
+ gl::GLWindowSystemBindingInfo *info)
+{
+ return gl::GetGLWindowSystemBindingInfoGLX(gl_info, info);
}
scoped_refptr<gl::GLContext> GLOzoneGLXQt::CreateGLContext(
diff --git a/src/core/ozone/gl_ozone_glx_qt.h b/src/core/ozone/gl_ozone_glx_qt.h
index ffbd60454..1596ea12f 100644
--- a/src/core/ozone/gl_ozone_glx_qt.h
+++ b/src/core/ozone/gl_ozone_glx_qt.h
@@ -60,7 +60,8 @@ public:
void SetDisabledExtensionsPlatform(
const std::string& disabled_extensions) override;
bool GetGLWindowSystemBindingInfo(
- gl::GLWindowSystemBindingInfo* info) override;
+ const gl::GLVersionInfo &gl_info,
+ gl::GLWindowSystemBindingInfo *info) override;
scoped_refptr<gl::GLContext> CreateGLContext(
gl::GLShareGroup* share_group,
diff --git a/src/core/ozone/gl_surface_egl_qt.cpp b/src/core/ozone/gl_surface_egl_qt.cpp
index 8715a5095..97c6cdee6 100644
--- a/src/core/ozone/gl_surface_egl_qt.cpp
+++ b/src/core/ozone/gl_surface_egl_qt.cpp
@@ -128,7 +128,7 @@ EGLDisplay GLSurfaceEGL::GetHardwareDisplay()
bool GLSurfaceEGL::IsCreateContextRobustnessSupported()
{
- return false;
+ return GLContextHelper::isCreateContextRobustnessSupported() && HasEGLExtension("EGL_EXT_create_context_robustness");
}
bool GLSurfaceEGL::IsCreateContextBindGeneratesResourceSupported()
@@ -164,6 +164,11 @@ bool GLSurfaceEGL::IsCreateContextClientArraysSupported()
return false;
}
+bool GLSurfaceEGL::IsPixelFormatFloatSupported()
+{
+ return false;
+}
+
void GLSurfaceEGL::ShutdownOneOff()
{
}
diff --git a/src/core/ozone/gl_surface_glx_qt.cpp b/src/core/ozone/gl_surface_glx_qt.cpp
index 24772889f..e150c940a 100644
--- a/src/core/ozone/gl_surface_glx_qt.cpp
+++ b/src/core/ozone/gl_surface_glx_qt.cpp
@@ -68,7 +68,7 @@ bool GLSurfaceGLX::IsCreateContextSupported()
bool GLSurfaceGLX::IsCreateContextRobustnessSupported()
{
- return false; // ExtensionsContain(g_extensions, "GLX_ARB_create_context_robustness");
+ return GLContextHelper::isCreateContextRobustnessSupported() && HasGLXExtension("GLX_ARB_create_context_robustness");
}
bool GLSurfaceGLX::IsEXTSwapControlSupported()
diff --git a/src/core/ozone/gl_surface_qt.cpp b/src/core/ozone/gl_surface_qt.cpp
index 551ba888c..82f8cd0e5 100644
--- a/src/core/ozone/gl_surface_qt.cpp
+++ b/src/core/ozone/gl_surface_qt.cpp
@@ -107,7 +107,7 @@ bool GLSurfaceQt::IsOffscreen()
return true;
}
-gfx::SwapResult GLSurfaceQt::SwapBuffers(const PresentationCallback &callback)
+gfx::SwapResult GLSurfaceQt::SwapBuffers(PresentationCallback callback)
{
LOG(ERROR) << "Attempted to call SwapBuffers on a pbuffer.";
Q_UNREACHABLE();
diff --git a/src/core/ozone/gl_surface_qt.h b/src/core/ozone/gl_surface_qt.h
index 514527df9..cbdc8876a 100644
--- a/src/core/ozone/gl_surface_qt.h
+++ b/src/core/ozone/gl_surface_qt.h
@@ -57,7 +57,7 @@ public:
void *GetDisplay() override;
void *GetConfig() override;
bool IsOffscreen() override;
- gfx::SwapResult SwapBuffers(const PresentationCallback &callback) override;
+ gfx::SwapResult SwapBuffers(PresentationCallback callback) override;
gfx::Size GetSize() override;
GLSurfaceFormat GetFormat() override;
diff --git a/src/core/platform_notification_service_qt.cpp b/src/core/platform_notification_service_qt.cpp
index f3457c7aa..d8abec17f 100644
--- a/src/core/platform_notification_service_qt.cpp
+++ b/src/core/platform_notification_service_qt.cpp
@@ -105,12 +105,13 @@ struct PersistentNotificationDelegate : UserNotificationController::Delegate {
};
-PlatformNotificationServiceQt::PlatformNotificationServiceQt() {}
+PlatformNotificationServiceQt::PlatformNotificationServiceQt(content::BrowserContext *browserContext)
+ : browser_context(browserContext)
+{}
PlatformNotificationServiceQt::~PlatformNotificationServiceQt() {}
void PlatformNotificationServiceQt::DisplayNotification(
- content::BrowserContext *browser_context,
const std::string &notification_id,
const GURL &origin,
const blink::PlatformNotificationData &notificationData,
@@ -131,7 +132,6 @@ void PlatformNotificationServiceQt::DisplayNotification(
}
void PlatformNotificationServiceQt::DisplayPersistentNotification(
- content::BrowserContext *browser_context,
const std::string &notification_id,
const GURL &service_worker_origin,
const GURL &origin,
@@ -151,9 +151,7 @@ void PlatformNotificationServiceQt::DisplayPersistentNotification(
client->showNotification(controller);
}
-void PlatformNotificationServiceQt::CloseNotification(
- content::BrowserContext *browser_context,
- const std::string &notification_id)
+void PlatformNotificationServiceQt::CloseNotification(const std::string &notification_id)
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
ProfileQt *profile = static_cast<ProfileQt*>(browser_context);
@@ -164,9 +162,7 @@ void PlatformNotificationServiceQt::CloseNotification(
notificationController->closeNotification();
}
-void PlatformNotificationServiceQt::ClosePersistentNotification(
- content::BrowserContext *browser_context,
- const std::string &notification_id)
+void PlatformNotificationServiceQt::ClosePersistentNotification(const std::string &notification_id)
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
ProfileQt *profile = static_cast<ProfileQt*>(browser_context);
@@ -177,26 +173,24 @@ void PlatformNotificationServiceQt::ClosePersistentNotification(
notificationController->closeNotification();
}
-void PlatformNotificationServiceQt::GetDisplayedNotifications(
- content::BrowserContext *browser_context,
- const DisplayedNotificationsCallback &callback)
+void PlatformNotificationServiceQt::GetDisplayedNotifications(DisplayedNotificationsCallback callback)
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
ProfileQt *profile = static_cast<ProfileQt *>(browser_context);
- std::unique_ptr<std::set<std::string>> movableStdStringSet = std::make_unique<std::set<std::string>>();
+ 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())
- movableStdStringSet->insert(it.key().toStdString());
+ movableStdStringSet.insert(it.key().toStdString());
++it;
}
- callback.Run(std::move(movableStdStringSet), true /* supports_synchronization */);
+ std::move(callback).Run(std::move(movableStdStringSet), true /* supports_synchronization */);
}
-int64_t PlatformNotificationServiceQt::ReadNextPersistentNotificationId(content::BrowserContext *browser_context)
+int64_t PlatformNotificationServiceQt::ReadNextPersistentNotificationId()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
auto prefs = static_cast<ProfileQt *>(browser_context)->GetPrefs();
@@ -205,4 +199,15 @@ int64_t PlatformNotificationServiceQt::ReadNextPersistentNotificationId(content:
return nextId;
}
+void PlatformNotificationServiceQt::ScheduleTrigger(base::Time /*timestamp*/)
+{
+ Q_UNIMPLEMENTED();
+}
+
+base::Time PlatformNotificationServiceQt::ReadNextTriggerTimestamp()
+{
+ Q_UNIMPLEMENTED();
+ return base::Time::Max();
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/platform_notification_service_qt.h b/src/core/platform_notification_service_qt.h
index 66cee9ed0..12aa2619b 100644
--- a/src/core/platform_notification_service_qt.h
+++ b/src/core/platform_notification_service_qt.h
@@ -42,26 +42,28 @@
#include "content/public/browser/platform_notification_service.h"
+namespace content {
+class BrowserContext;
+}
+
namespace QtWebEngineCore {
class PlatformNotificationServiceQt : public content::PlatformNotificationService {
public:
- PlatformNotificationServiceQt();
+ PlatformNotificationServiceQt(content::BrowserContext *browserContext);
~PlatformNotificationServiceQt() override;
// Displays the notification described in |notification_data| to the user. A
// closure through which the notification can be closed will be stored in the
// |cancel_callback| argument. This method must be called on the UI thread.
- void DisplayNotification(content::BrowserContext* browser_context,
- const std::string& notification_id,
+ void DisplayNotification(const std::string& notification_id,
const GURL& origin,
const blink::PlatformNotificationData& notificationData,
const blink::NotificationResources& notificationResources) override;
// Displays the persistent notification described in |notification_data| to
// the user. This method must be called on the UI thread.
- void DisplayPersistentNotification(content::BrowserContext* browser_context,
- const std::string& notification_id,
+ void DisplayPersistentNotification(const std::string& notification_id,
const GURL& service_worker_origin,
const GURL& origin,
const blink::PlatformNotificationData& notification_data,
@@ -69,22 +71,27 @@ public:
// Closes the notification identified by |notification_id|.
// This method must be called on the UI thread.
- void CloseNotification(content::BrowserContext* browser_context, const std::string& notification_id) override;
+ void CloseNotification(const std::string& notification_id) override;
// Closes the persistent notification identified by |persistent_notification_id|.
// This method must be called on the UI thread.
- void ClosePersistentNotification(content::BrowserContext* browser_context, const std::string& notification_id) override;
+ void ClosePersistentNotification(const std::string& notification_id) override;
// Retrieves the ids of all currently displaying notifications and
// posts |callback| with the result.
- void GetDisplayedNotifications(content::BrowserContext* browser_context, const DisplayedNotificationsCallback& callback) override;
+ void GetDisplayedNotifications(DisplayedNotificationsCallback callback) override;
// Reads the value of the next persistent notification ID from the profile and
// increments the value, as it is called once per notification write.
- virtual int64_t ReadNextPersistentNotificationId(content::BrowserContext* browser_context) override;
+ int64_t ReadNextPersistentNotificationId() override;
+
+ void ScheduleTrigger(base::Time timestamp) override;
+ base::Time ReadNextTriggerTimestamp() override;
// Records a given notification to UKM.
- virtual void RecordNotificationUkmEvent(content::BrowserContext*, const content::NotificationDatabaseData&) override { }
+ void RecordNotificationUkmEvent(const content::NotificationDatabaseData&) override { }
+
+ content::BrowserContext *browser_context;
};
} // namespace QtWebEngineCore
diff --git a/src/core/pref_service_adapter.cpp b/src/core/pref_service_adapter.cpp
new file mode 100644
index 000000000..8a33a4b60
--- /dev/null
+++ b/src/core/pref_service_adapter.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "pref_service_adapter.h"
+
+#include "command_line_pref_store_qt.h"
+#include "profile_adapter.h"
+#include "type_conversion.h"
+#include "web_engine_context.h"
+
+#include "content/public/browser/browser_thread.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/user_prefs/user_prefs.h"
+#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
+#include "chrome/common/pref_names.h"
+#include "extensions/buildflags/buildflags.h"
+#include "content/public/browser/browser_context.h"
+
+#if QT_CONFIG(webengine_spellchecker)
+#include "chrome/browser/spellchecker/spellcheck_service.h"
+#include "components/spellcheck/browser/pref_names.h"
+#endif
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "components/guest_view/browser/guest_view_manager.h"
+#include "extensions/browser/extension_protocols.h"
+#include "extensions/browser/pref_names.h"
+#include "extensions/browser/process_manager.h"
+#include "extensions/common/constants.h"
+#endif
+
+namespace {
+static const char kPrefMediaDeviceIDSalt[] = "qtwebengine.media_device_salt_id";
+}
+
+namespace QtWebEngineCore {
+
+void PrefServiceAdapter::setup(const ProfileAdapter &profileAdapter)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ PrefServiceFactory factory;
+ factory.set_command_line_prefs(base::MakeRefCounted<CommandLinePrefStoreQt>(
+ WebEngineContext::commandLine()));
+
+ QString userPrefStorePath = profileAdapter.dataPath();
+ if (userPrefStorePath.isEmpty() || profileAdapter.isOffTheRecord()) {
+ factory.set_user_prefs(new InMemoryPrefStore);
+ } else {
+ userPrefStorePath += QDir::separator();
+ userPrefStorePath += QStringLiteral("user_prefs.json");
+ factory.set_user_prefs(base::MakeRefCounted<JsonPrefStore>(toFilePath(userPrefStorePath)));
+ }
+
+ PrefRegistrySimple *registry = new PrefRegistrySimple();
+ PrefProxyConfigTrackerImpl::RegisterPrefs(registry);
+
+#if QT_CONFIG(webengine_spellchecker)
+ // Initial spellcheck settings
+ registry->RegisterStringPref(prefs::kAcceptLanguages, std::string());
+ registry->RegisterListPref(spellcheck::prefs::kSpellCheckDictionaries);
+ registry->RegisterListPref(spellcheck::prefs::kSpellCheckForcedDictionaries);
+ registry->RegisterListPref(spellcheck::prefs::kSpellCheckBlacklistedDictionaries);
+ registry->RegisterStringPref(spellcheck::prefs::kSpellCheckDictionary, std::string());
+ registry->RegisterBooleanPref(spellcheck::prefs::kSpellCheckEnable, false);
+ registry->RegisterBooleanPref(spellcheck::prefs::kSpellCheckUseSpellingService, false);
+#endif // QT_CONFIG(webengine_spellchecker)
+ registry->RegisterBooleanPref(prefs::kShowInternalAccessibilityTree, false);
+ registry->RegisterIntegerPref(prefs::kNotificationNextPersistentId, 10000);
+
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ registry->RegisterDictionaryPref(extensions::pref_names::kExtensions);
+ registry->RegisterListPref(extensions::pref_names::kInstallAllowList);
+ registry->RegisterListPref(extensions::pref_names::kInstallDenyList);
+ registry->RegisterDictionaryPref(extensions::pref_names::kInstallForceList);
+ registry->RegisterDictionaryPref(extensions::pref_names::kLoginScreenExtensions);
+ registry->RegisterListPref(extensions::pref_names::kAllowedTypes);
+ registry->RegisterBooleanPref(extensions::pref_names::kStorageGarbageCollect, false);
+ registry->RegisterListPref(extensions::pref_names::kAllowedInstallSites);
+ registry->RegisterStringPref(extensions::pref_names::kLastChromeVersion, std::string());
+ registry->RegisterListPref(extensions::pref_names::kNativeMessagingBlacklist);
+ registry->RegisterListPref(extensions::pref_names::kNativeMessagingWhitelist);
+ registry->RegisterBooleanPref(extensions::pref_names::kNativeMessagingUserLevelHosts, true);
+ registry->RegisterBooleanPref(extensions::pref_names::kInsecureExtensionUpdatesEnabled, false);
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
+
+ // Media device salt id key
+ // Can't be a random value since every time we run the setup code the
+ // default value will be different. We'll need to initialize it later.
+ registry->RegisterStringPref(kPrefMediaDeviceIDSalt, std::string());
+
+ m_prefService = factory.Create(registry);
+
+ // Initialize salt value if none was stored before
+ if (m_prefService->GetString(kPrefMediaDeviceIDSalt).empty()) {
+ m_prefService->SetString(kPrefMediaDeviceIDSalt,
+ content::BrowserContext::CreateRandomMediaDeviceIDSalt());
+ }
+
+#if QT_CONFIG(webengine_spellchecker)
+ // Ignore stored values for these options to preserve backwards compatibility.
+ m_prefService->ClearPref(spellcheck::prefs::kSpellCheckEnable);
+ m_prefService->ClearPref(spellcheck::prefs::kSpellCheckDictionaries);
+#endif // QT_CONFIG(webengine_spellchecker)
+}
+
+void PrefServiceAdapter::commit()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ // Make sure modified preferences are written to disk
+ m_prefService->CommitPendingWrite();
+}
+
+PrefService* PrefServiceAdapter::prefService()
+{
+ return m_prefService.get();
+}
+
+const PrefService* PrefServiceAdapter::prefService() const
+{
+ return m_prefService.get();
+}
+
+std::string PrefServiceAdapter::mediaDeviceIdSalt() const
+{
+ return m_prefService->GetString(kPrefMediaDeviceIDSalt);
+}
+
+#if QT_CONFIG(webengine_spellchecker)
+
+void PrefServiceAdapter::setSpellCheckLanguages(const QStringList &languages)
+{
+ StringListPrefMember dictionaries_pref;
+ dictionaries_pref.Init(spellcheck::prefs::kSpellCheckDictionaries, m_prefService.get());
+ std::vector<std::string> dictionaries;
+ dictionaries.reserve(languages.size());
+ for (const auto &language : languages)
+ dictionaries.push_back(language.toStdString());
+ dictionaries_pref.SetValue(dictionaries);
+}
+
+QStringList PrefServiceAdapter::spellCheckLanguages() const
+{
+ QStringList spellcheck_dictionaries;
+ for (const auto &value : *m_prefService->GetList(spellcheck::prefs::kSpellCheckDictionaries)) {
+ std::string dictionary;
+ if (value.GetAsString(&dictionary))
+ spellcheck_dictionaries.append(QString::fromStdString(dictionary));
+ }
+
+ return spellcheck_dictionaries;
+}
+
+void PrefServiceAdapter::setSpellCheckEnabled(bool enabled)
+{
+ m_prefService->SetBoolean(spellcheck::prefs::kSpellCheckEnable, enabled);
+}
+
+bool PrefServiceAdapter::isSpellCheckEnabled() const
+{
+ return m_prefService->GetBoolean(spellcheck::prefs::kSpellCheckEnable);
+}
+
+#endif // QT_CONFIG(webengine_spellchecker)
+}
diff --git a/src/core/pref_service_adapter.h b/src/core/pref_service_adapter.h
new file mode 100644
index 000000000..1c7c44a96
--- /dev/null
+++ b/src/core/pref_service_adapter.h
@@ -0,0 +1,85 @@
+
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PREF_SERVICE_ADAPTER_H
+#define PREF_SERVICE_ADAPTER_H
+
+#include "components/prefs/pref_service.h"
+#include "qtwebenginecoreglobal_p.h"
+
+QT_BEGIN_NAMESPACE
+class QStringList;
+QT_END_NAMESPACE
+
+class ProfileAdapter;
+
+namespace QtWebEngineCore {
+
+class ProfileAdapter;
+
+// PrefServiceAdapter manages the collection of tunable preferences.
+// Any new preference should be defined and register in the registry
+// before it can be used
+class PrefServiceAdapter
+{
+public:
+
+ PrefServiceAdapter() = default;
+
+ void setup(const ProfileAdapter &adapter);
+ void commit();
+ PrefService *prefService();
+ const PrefService *prefService() const;
+ std::string mediaDeviceIdSalt() const;
+
+#if QT_CONFIG(webengine_spellchecker)
+ void setSpellCheckLanguages(const QStringList &languages);
+ QStringList spellCheckLanguages() const;
+ void setSpellCheckEnabled(bool enabled);
+ bool isSpellCheckEnabled() const;
+#endif // QT_CONFIG(webengine_spellchecker)
+
+private:
+ std::unique_ptr<PrefService> m_prefService;
+};
+
+}
+
+#endif // PREF_SERVICE_ADAPTER_H
diff --git a/src/core/printing/print_view_manager_qt.cpp b/src/core/printing/print_view_manager_qt.cpp
index b6a2b42ec..7d8039100 100644
--- a/src/core/printing/print_view_manager_qt.cpp
+++ b/src/core/printing/print_view_manager_qt.cpp
@@ -98,7 +98,6 @@ static void SavePdfFile(scoped_refptr<base::RefCountedBytes> data,
const base::FilePath &path,
const QtWebEngineCore::PrintViewManagerQt::PrintToPDFFileCallback &saveCallback)
{
- base::AssertBlockingAllowedDeprecated();
DCHECK_GT(data->size(), 0U);
printing::MetafileSkia metafile;
diff --git a/src/core/printing/print_view_manager_qt.h b/src/core/printing/print_view_manager_qt.h
index 20b988200..14f2688dd 100644
--- a/src/core/printing/print_view_manager_qt.h
+++ b/src/core/printing/print_view_manager_qt.h
@@ -137,7 +137,7 @@ private:
void PrintPreviewDone();
private:
- WEB_CONTENTS_USER_DATA_KEY_DECL()
+ WEB_CONTENTS_USER_DATA_KEY_DECL();
content::RenderFrameHost *m_printPreviewRfh;
base::FilePath m_pdfOutputPath;
PrintToPDFCallback m_pdfPrintCallback;
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index ebb533206..551663cf0 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -57,6 +57,8 @@
#include "web_engine_context.h"
#include "web_contents_adapter_client.h"
+#include "base/files/file_util.h"
+#include "base/time/time_to_iso8601.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
@@ -126,6 +128,7 @@ void ProfileAdapter::setStorageName(const QString &storageName)
return;
m_name = storageName;
if (!m_offTheRecord) {
+ m_profile->setupPrefService();
if (m_profile->m_urlRequestContextGetter.get())
m_profile->m_profileIOData->updateStorageSettings();
if (m_visitedLinksManager)
@@ -138,6 +141,7 @@ void ProfileAdapter::setOffTheRecord(bool offTheRecord)
if (offTheRecord == m_offTheRecord)
return;
m_offTheRecord = offTheRecord;
+ m_profile->setupPrefService();
if (m_profile->m_urlRequestContextGetter.get())
m_profile->m_profileIOData->updateStorageSettings();
if (m_visitedLinksManager)
@@ -263,6 +267,7 @@ void ProfileAdapter::setDataPath(const QString &path)
return;
m_dataPath = path;
if (!m_offTheRecord) {
+ m_profile->setupPrefService();
if (m_profile->m_urlRequestContextGetter.get())
m_profile->m_profileIOData->updateStorageSettings();
if (m_visitedLinksManager)
@@ -310,16 +315,6 @@ QString ProfileAdapter::cookiesPath() const
return QString();
}
-QString ProfileAdapter::channelIdPath() const
-{
- if (m_offTheRecord)
- return QString();
- QString basePath = dataPath();
- if (!basePath.isEmpty())
- return basePath % QLatin1String("/Origin Bound Certs");
- return QString();
-}
-
QString ProfileAdapter::httpCachePath() const
{
if (m_offTheRecord)
@@ -595,7 +590,7 @@ void ProfileAdapter::setHttpAcceptLanguage(const QString &httpAcceptLanguage)
std::vector<content::WebContentsImpl *> list = content::WebContentsImpl::GetAllWebContents();
for (content::WebContentsImpl *web_contents : list) {
if (web_contents->GetBrowserContext() == m_profile.data()) {
- content::RendererPreferences* rendererPrefs = web_contents->GetMutableRendererPrefs();
+ blink::mojom::RendererPreferences *rendererPrefs = web_contents->GetMutableRendererPrefs();
rendererPrefs->accept_languages = httpAcceptLanguageWithoutQualities().toStdString();
web_contents->GetRenderViewHost()->SyncRendererPrefs();
}
@@ -616,14 +611,14 @@ void ProfileAdapter::clearHttpCache()
void ProfileAdapter::setSpellCheckLanguages(const QStringList &languages)
{
#if QT_CONFIG(webengine_spellchecker)
- m_profile->setSpellCheckLanguages(languages);
+ m_profile->prefServiceAdapter().setSpellCheckLanguages(languages);
#endif
}
QStringList ProfileAdapter::spellCheckLanguages() const
{
#if QT_CONFIG(webengine_spellchecker)
- return m_profile->spellCheckLanguages();
+ return m_profile->prefServiceAdapter().spellCheckLanguages();
#else
return QStringList();
#endif
@@ -632,14 +627,14 @@ QStringList ProfileAdapter::spellCheckLanguages() const
void ProfileAdapter::setSpellCheckEnabled(bool enabled)
{
#if QT_CONFIG(webengine_spellchecker)
- m_profile->setSpellCheckEnabled(enabled);
+ m_profile->prefServiceAdapter().setSpellCheckEnabled(enabled);
#endif
}
bool ProfileAdapter::isSpellCheckEnabled() const
{
#if QT_CONFIG(webengine_spellchecker)
- return m_profile->isSpellCheckEnabled();
+ return m_profile->prefServiceAdapter().isSpellCheckEnabled();
#else
return false;
#endif
@@ -690,6 +685,34 @@ bool ProfileAdapter::isUsedForGlobalCertificateVerification() const
return m_usedForGlobalCertificateVerification;
}
+QString ProfileAdapter::determineDownloadPath(const QString &downloadDirectory, const QString &suggestedFilename, const time_t &startTime)
+{
+ QFileInfo suggestedFile(QDir(downloadDirectory).absoluteFilePath(suggestedFilename));
+ QString suggestedFilePath = suggestedFile.absoluteFilePath();
+ base::FilePath tmpFilePath(toFilePath(suggestedFilePath).NormalizePathSeparatorsTo('/'));
+
+ int uniquifier = base::GetUniquePathNumber(tmpFilePath, base::FilePath::StringType());
+ if (uniquifier > 0)
+ suggestedFilePath = toQt(tmpFilePath.InsertBeforeExtensionASCII(base::StringPrintf(" (%d)", uniquifier)).AsUTF8Unsafe());
+ else if (uniquifier == -1) {
+ base::Time::Exploded exploded;
+ base::Time::FromTimeT(startTime).LocalExplode(&exploded);
+ std::string suffix = base::StringPrintf(
+ " - %04d-%02d-%02dT%02d%02d%02d.%03d", exploded.year, exploded.month,
+ exploded.day_of_month, exploded.hour, exploded.minute,
+ exploded.second, exploded.millisecond);
+ suggestedFilePath = toQt(tmpFilePath.InsertBeforeExtensionASCII(suffix).AsUTF8Unsafe());
+ }
+ return suggestedFilePath;
+}
+
+QString ProfileAdapter::updateDownloadPath(int downloadId, const QString &directory, const QString &fileName)
+{
+ download::DownloadItem *download = m_downloadManagerDelegate->findDownloadById(downloadId);
+ Q_ASSERT(download);
+ return determineDownloadPath(directory, fileName, download->GetStartTime().ToTimeT());
+}
+
#if QT_CONFIG(ssl)
QWebEngineClientCertificateStore *ProfileAdapter::clientCertificateStore()
{
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index 1f94f59a9..01477d0d9 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -124,7 +124,6 @@ public:
QString httpCachePath() const;
QString cookiesPath() const;
- QString channelIdPath() const;
QString httpUserAgent() const;
void setHttpUserAgent(const QString &userAgent);
@@ -214,6 +213,9 @@ public:
QHash<QByteArray, QSharedPointer<UserNotificationController>> &persistentNotifications()
{ return m_persistentNotifications; }
+ QString determineDownloadPath(const QString &downloadDirectory, const QString &suggestedFilename, const time_t &startTime);
+ QString updateDownloadPath(int downloadId, const QString &directory, const QString &filename);
+
private:
void updateCustomUrlSchemeHandlers();
void resetVisitedLinksManager();
diff --git a/src/core/profile_adapter_client.h b/src/core/profile_adapter_client.h
index b463043da..dc0f508a1 100644
--- a/src/core/profile_adapter_client.h
+++ b/src/core/profile_adapter_client.h
@@ -55,6 +55,7 @@
#include <QSharedPointer>
#include <QString>
#include <QUrl>
+#include <time.h>
namespace QtWebEngineCore {
@@ -138,6 +139,8 @@ public:
int downloadType;
int downloadInterruptReason;
WebContentsAdapterClient *page;
+ QString suggestedFileName;
+ time_t startTime;
};
virtual ~ProfileAdapterClient() { }
diff --git a/src/core/profile_io_data_qt.cpp b/src/core/profile_io_data_qt.cpp
index 27c97a986..5c87d87a2 100644
--- a/src/core/profile_io_data_qt.cpp
+++ b/src/core/profile_io_data_qt.cpp
@@ -55,7 +55,7 @@
#include "net/cert/ct_log_verifier.h"
#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/multi_log_ct_verifier.h"
-#include "net/extras/sqlite/sqlite_channel_id_store.h"
+#include "net/dns/host_resolver_manager.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_auth_scheme.h"
#include "net/http/http_auth_preferences.h"
@@ -68,6 +68,7 @@
#include "net/proxy_resolution/proxy_config_service.h"
#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/ssl/channel_id_service.h"
+#include "net/ssl/default_channel_id_store.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "net/url_request/data_protocol_handler.h"
#include "net/url_request/file_protocol_handler.h"
@@ -99,6 +100,8 @@
#include "net/cert_net/cert_net_fetcher_impl.h"
#endif
+#include <mutex>
+
namespace QtWebEngineCore {
static bool doNetworkSessionParamsMatch(const net::HttpNetworkSession::Params &first,
@@ -106,8 +109,6 @@ static bool doNetworkSessionParamsMatch(const net::HttpNetworkSession::Params &f
{
if (first.ignore_certificate_errors != second.ignore_certificate_errors)
return false;
- if (first.enable_channel_id != second.enable_channel_id)
- return false;
return true;
}
@@ -118,14 +119,14 @@ static bool doNetworkSessionContextMatch(const net::HttpNetworkSession::Context
return false;
if (first.cert_verifier != second.cert_verifier)
return false;
- if (first.channel_id_service != second.channel_id_service)
- return false;
if (first.proxy_resolution_service != second.proxy_resolution_service)
return false;
if (first.ssl_config_service != second.ssl_config_service)
return false;
if (first.http_auth_handler_factory != second.http_auth_handler_factory)
return false;
+ if (first.http_user_agent_settings != second.http_user_agent_settings)
+ return false;
if (first.http_server_properties != second.http_server_properties)
return false;
if (first.host_resolver != second.host_resolver)
@@ -142,10 +143,10 @@ static net::HttpNetworkSession::Context generateNetworkSessionContext(net::URLRe
net::HttpNetworkSession::Context network_session_context;
network_session_context.transport_security_state = urlRequestContext->transport_security_state();
network_session_context.cert_verifier = urlRequestContext->cert_verifier();
- network_session_context.channel_id_service = urlRequestContext->channel_id_service();
network_session_context.proxy_resolution_service = urlRequestContext->proxy_resolution_service();
network_session_context.ssl_config_service = urlRequestContext->ssl_config_service();
network_session_context.http_auth_handler_factory = urlRequestContext->http_auth_handler_factory();
+ network_session_context.http_user_agent_settings = urlRequestContext->http_user_agent_settings();
network_session_context.http_server_properties = urlRequestContext->http_server_properties();
network_session_context.host_resolver = urlRequestContext->host_resolver();
network_session_context.cert_transparency_verifier = urlRequestContext->cert_transparency_verifier();
@@ -165,7 +166,6 @@ ProfileIODataQt::ProfileIODataQt(ProfileQt *profile)
#if QT_CONFIG(ssl)
m_clientCertificateStoreData(new ClientCertificateStoreData),
#endif
- m_mutex(QMutex::Recursive),
m_removerObserver(this),
m_weakPtrFactory(this)
{
@@ -239,14 +239,14 @@ extensions::ExtensionSystemQt* ProfileIODataQt::GetExtensionSystem()
void ProfileIODataQt::initializeOnIOThread()
{
m_networkDelegate.reset(new NetworkDelegateQt(this));
- m_hostResolver = net::HostResolver::CreateDefaultResolver(NULL);
+ m_hostResolver = net::HostResolver::CreateStandaloneResolver(nullptr);
m_urlRequestContext.reset(new net::URLRequestContext());
m_urlRequestContext->set_network_delegate(m_networkDelegate.get());
m_urlRequestContext->set_enable_brotli(base::FeatureList::IsEnabled(features::kBrotliEncoding));
m_urlRequestContext->set_host_resolver(m_hostResolver.get());
// this binds factory to io thread
m_weakPtr = m_weakPtrFactory.GetWeakPtr();
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
generateAllStorage();
generateJobFactory();
setGlobalCertificateVerification();
@@ -286,7 +286,7 @@ void ProfileIODataQt::cancelAllUrlRequests()
void ProfileIODataQt::generateAllStorage()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
generateStorage();
generateCookieStore();
generateUserAgent();
@@ -298,6 +298,7 @@ void ProfileIODataQt::generateStorage()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
Q_ASSERT(m_urlRequestContext);
+// Q_ASSERT(!m_mutex.tryLock()); // assert locked
// We must stop all requests before deleting their backends.
if (m_storage) {
@@ -346,7 +347,6 @@ void ProfileIODataQt::generateStorage()
m_httpAuthPreferences->SetServerWhitelist(serverWhitelist);
}
m_storage->set_http_auth_handler_factory(net::HttpAuthHandlerFactory::CreateDefault(
- m_urlRequestContext->host_resolver(),
m_httpAuthPreferences.get()));
m_storage->set_transport_security_state(std::make_unique<net::TransportSecurityState>());
@@ -388,19 +388,11 @@ void ProfileIODataQt::generateCookieStore()
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
Q_ASSERT(m_urlRequestContext);
- QMutexLocker lock(&m_mutex);
-
- scoped_refptr<net::SQLiteChannelIDStore> channel_id_db;
- if (!m_channelIdPath.isEmpty() && m_persistentCookiesPolicy != ProfileAdapter::NoPersistentCookies) {
- channel_id_db = new net::SQLiteChannelIDStore(
- toFilePath(m_channelIdPath),
- base::CreateSequencedTaskRunnerWithTraits(
- {base::MayBlock(), base::TaskPriority::BEST_EFFORT}));
- }
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
+ // FIXME: Add code to remove the old database.
m_storage->set_channel_id_service(
- base::WrapUnique(new net::ChannelIDService(
- new net::DefaultChannelIDStore(channel_id_db.get()))));
+ std::make_unique<net::ChannelIDService>(new net::DefaultChannelIDStore(nullptr)));
std::unique_ptr<net::CookieStore> cookieStore;
switch (m_persistentCookiesPolicy) {
@@ -440,7 +432,7 @@ void ProfileIODataQt::generateCookieStore()
const std::vector<std::string> cookieableSchemes(kCookieableSchemes,
kCookieableSchemes + base::size(kCookieableSchemes));
- cookieMonster->SetCookieableSchemes(cookieableSchemes);
+ cookieMonster->SetCookieableSchemes(cookieableSchemes, base::DoNothing());
}
void ProfileIODataQt::generateUserAgent()
@@ -449,7 +441,7 @@ void ProfileIODataQt::generateUserAgent()
Q_ASSERT(m_urlRequestContext);
Q_ASSERT(m_storage);
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
m_storage->set_http_user_agent_settings(std::unique_ptr<net::HttpUserAgentSettings>(
new net::StaticHttpUserAgentSettings(m_httpAcceptLanguage.toStdString(),
m_httpUserAgent.toStdString())));
@@ -461,7 +453,7 @@ void ProfileIODataQt::generateHttpCache()
Q_ASSERT(m_urlRequestContext);
Q_ASSERT(m_storage);
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
net::HttpCache::DefaultBackend* main_backend = 0;
switch (m_httpCacheType) {
@@ -514,7 +506,7 @@ void ProfileIODataQt::generateJobFactory()
Q_ASSERT(m_urlRequestContext);
Q_ASSERT(!m_jobFactory);
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
m_updateJobFactory = false;
std::unique_ptr<net::URLRequestJobFactoryImpl> jobFactory(new net::URLRequestJobFactoryImpl());
@@ -569,7 +561,7 @@ void ProfileIODataQt::regenerateJobFactory()
Q_ASSERT(m_jobFactory);
Q_ASSERT(m_baseJobFactory);
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
m_updateJobFactory = false;
if (m_customUrlSchemes == m_installedCustomSchemes)
@@ -590,7 +582,7 @@ void ProfileIODataQt::regenerateJobFactory()
void ProfileIODataQt::setGlobalCertificateVerification()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
if (m_useForGlobalCertificateVerification) {
#if defined(USE_NSS_CERTS)
// Set request context used by NSS for OCSP requests.
@@ -617,7 +609,6 @@ void ProfileIODataQt::setFullConfiguration()
m_requestInterceptor = m_profileAdapter->requestInterceptor();
m_persistentCookiesPolicy = m_profileAdapter->persistentCookiesPolicy();
m_cookiesPath = m_profileAdapter->cookiesPath();
- m_channelIdPath = m_profileAdapter->channelIdPath();
m_httpAcceptLanguage = m_profileAdapter->httpAcceptLanguage();
m_httpUserAgent = m_profileAdapter->httpUserAgent();
m_httpCacheType = m_profileAdapter->httpCacheType();
@@ -630,7 +621,7 @@ void ProfileIODataQt::setFullConfiguration()
void ProfileIODataQt::requestStorageGeneration() {
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
if (m_initialized && !m_updateAllStorage) {
m_updateAllStorage = true;
createProxyConfig();
@@ -643,7 +634,7 @@ void ProfileIODataQt::requestStorageGeneration() {
void ProfileIODataQt::createProxyConfig()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
// We must create the proxy config service on the UI loop on Linux because it
// must synchronously run on the glib message loop. This will be passed to
// the URLRequestContextStorage on the IO thread in GetURLRequestContext().
@@ -664,7 +655,7 @@ void ProfileIODataQt::updateStorageSettings()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
setFullConfiguration();
base::Token groupId = content::BrowserContext::GetServiceInstanceGroupFor(m_profile);
@@ -679,10 +670,9 @@ void ProfileIODataQt::updateStorageSettings()
void ProfileIODataQt::updateCookieStore()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
m_persistentCookiesPolicy = m_profileAdapter->persistentCookiesPolicy();
m_cookiesPath = m_profileAdapter->cookiesPath();
- m_channelIdPath = m_profileAdapter->channelIdPath();
if (!m_pendingStorageRequestGeneration)
requestStorageGeneration();
}
@@ -690,7 +680,7 @@ void ProfileIODataQt::updateCookieStore()
void ProfileIODataQt::updateUserAgent()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
m_httpAcceptLanguage = m_profileAdapter->httpAcceptLanguage();
m_httpUserAgent = m_profileAdapter->httpUserAgent();
if (!m_pendingStorageRequestGeneration)
@@ -700,7 +690,7 @@ void ProfileIODataQt::updateUserAgent()
void ProfileIODataQt::updateHttpCache()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
m_httpCacheType = m_profileAdapter->httpCacheType();
m_httpCachePath = m_profileAdapter->httpCachePath();
m_httpCacheMaxSize = m_profileAdapter->httpCacheMaxSize();
@@ -724,7 +714,7 @@ void ProfileIODataQt::updateHttpCache()
void ProfileIODataQt::updateJobFactory()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
m_customUrlSchemes = m_profileAdapter->customUrlSchemes();
@@ -738,7 +728,7 @@ void ProfileIODataQt::updateJobFactory()
void ProfileIODataQt::updateRequestInterceptor()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
m_requestInterceptor = m_profileAdapter->requestInterceptor();
m_hasPageInterceptors = m_profileAdapter->hasPageRequestInterceptor();
// We in this case do not need to regenerate any Chromium classes.
@@ -780,7 +770,7 @@ bool ProfileIODataQt::canGetCookies(const QUrl &firstPartyUrl, const QUrl &url)
void ProfileIODataQt::updateUsedForGlobalCertificateVerification()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
m_useForGlobalCertificateVerification = m_profileAdapter->isUsedForGlobalCertificateVerification();
if (m_useForGlobalCertificateVerification)
diff --git a/src/core/profile_io_data_qt.h b/src/core/profile_io_data_qt.h
index 570365085..00a4de2b0 100644
--- a/src/core/profile_io_data_qt.h
+++ b/src/core/profile_io_data_qt.h
@@ -56,6 +56,7 @@ class ClientCertStore;
class DhcpPacFileFetcherFactory;
class HttpAuthPreferences;
class HttpNetworkSession;
+class HostResolver;
class NetworkDelegate;
class ProxyConfigService;
class URLRequestContext;
@@ -171,7 +172,6 @@ private:
ClientCertificateStoreData *m_clientCertificateStoreData;
#endif
QString m_cookiesPath;
- QString m_channelIdPath;
QString m_httpAcceptLanguage;
QString m_httpUserAgent;
ProfileAdapter::HttpCacheType m_httpCacheType;
@@ -179,7 +179,12 @@ private:
QList<QByteArray> m_customUrlSchemes;
QList<QByteArray> m_installedCustomSchemes;
QWebEngineUrlRequestInterceptor* m_requestInterceptor = nullptr;
- QMutex m_mutex;
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
+ QMutex m_mutex{QMutex::Recursive};
+ using QRecursiveMutex = QMutex;
+#else
+ QRecursiveMutex m_mutex;
+#endif
int m_httpCacheMaxSize = 0;
bool m_initialized = false;
bool m_updateAllStorage = false;
diff --git a/src/core/profile_qt.cpp b/src/core/profile_qt.cpp
index 5977a28a8..19d54df62 100644
--- a/src/core/profile_qt.cpp
+++ b/src/core/profile_qt.cpp
@@ -46,6 +46,7 @@
#include "net/ssl_host_state_delegate_qt.h"
#include "net/url_request_context_getter_qt.h"
#include "permission_manager_qt.h"
+#include "platform_notification_service_qt.h"
#include "qtwebenginecoreglobal_p.h"
#include "type_conversion.h"
#include "web_engine_library_info.h"
@@ -61,6 +62,7 @@
#include "components/prefs/pref_member.h"
#include "components/prefs/pref_service.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"
@@ -92,41 +94,7 @@ ProfileQt::ProfileQt(ProfileAdapter *profileAdapter)
, m_extensionSystem(nullptr)
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
{
- PrefServiceFactory factory;
- factory.set_user_prefs(new InMemoryPrefStore);
- factory.set_command_line_prefs(base::MakeRefCounted<CommandLinePrefStoreQt>(
- WebEngineContext::commandLine()));
- PrefRegistrySimple *registry = new PrefRegistrySimple();
- PrefProxyConfigTrackerImpl::RegisterPrefs(registry);
-#if QT_CONFIG(webengine_spellchecker)
- // Initial spellcheck settings
- registry->RegisterStringPref(prefs::kAcceptLanguages, std::string());
- registry->RegisterListPref(spellcheck::prefs::kSpellCheckDictionaries, std::make_unique<base::ListValue>());
- registry->RegisterListPref(spellcheck::prefs::kSpellCheckForcedDictionaries, std::make_unique<base::ListValue>());
- registry->RegisterStringPref(spellcheck::prefs::kSpellCheckDictionary, std::string());
- registry->RegisterBooleanPref(spellcheck::prefs::kSpellCheckEnable, false);
- registry->RegisterBooleanPref(spellcheck::prefs::kSpellCheckUseSpellingService, false);
-#endif // QT_CONFIG(webengine_spellchecker)
- registry->RegisterBooleanPref(prefs::kShowInternalAccessibilityTree, false);
- registry->RegisterIntegerPref(prefs::kNotificationNextPersistentId, 10000);
-
-#if BUILDFLAG(ENABLE_EXTENSIONS)
- registry->RegisterDictionaryPref(extensions::pref_names::kExtensions);
- registry->RegisterListPref(extensions::pref_names::kInstallAllowList);
- registry->RegisterListPref(extensions::pref_names::kInstallDenyList);
- registry->RegisterDictionaryPref(extensions::pref_names::kInstallForceList);
- registry->RegisterDictionaryPref(extensions::pref_names::kInstallLoginScreenAppList);
- registry->RegisterListPref(extensions::pref_names::kAllowedTypes);
- registry->RegisterBooleanPref(extensions::pref_names::kStorageGarbageCollect, false);
- registry->RegisterListPref(extensions::pref_names::kAllowedInstallSites);
- registry->RegisterStringPref(extensions::pref_names::kLastChromeVersion, std::string());
- registry->RegisterListPref(extensions::pref_names::kNativeMessagingBlacklist);
- registry->RegisterListPref(extensions::pref_names::kNativeMessagingWhitelist);
- registry->RegisterBooleanPref(extensions::pref_names::kNativeMessagingUserLevelHosts, true);
-#endif // BUILDFLAG(ENABLE_EXTENSIONS)
-
- m_prefService = factory.Create(registry);
- user_prefs::UserPrefs::Set(this, m_prefService.get());
+ setupPrefService();
// Mark the context as live. This prevents the use-after-free DCHECK in
// AssertBrowserContextWasntDestroyed from being triggered when a new
@@ -143,6 +111,7 @@ ProfileQt::ProfileQt(ProfileAdapter *profileAdapter)
ProfileQt::~ProfileQt()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ m_prefServiceAdapter.commit();
content::BrowserContext::NotifyWillBeDestroyed(this);
BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(this);
ShutdownStoragePartitions();
@@ -153,12 +122,12 @@ ProfileQt::~ProfileQt()
PrefService* ProfileQt::GetPrefs()
{
- return m_prefService.get();
+ return m_prefServiceAdapter.prefService();
}
const PrefService* ProfileQt::GetPrefs() const
{
- return m_prefService.get();
+ return m_prefServiceAdapter.prefService();
}
base::FilePath ProfileQt::GetPath() const
@@ -313,46 +282,48 @@ void ProfileQt::FailedToLoadDictionary(const std::string &language)
LOG(WARNING) << "Could not load dictionary for:" << language;
LOG(INFO) << "Make sure that correct bdic file is in:" << WebEngineLibraryInfo::getPath(base::DIR_APP_DICTIONARIES);
}
+#endif // QT_CONFIG(webengine_spellchecker)
-void ProfileQt::setSpellCheckLanguages(const QStringList &languages)
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+extensions::ExtensionSystemQt* ProfileQt::GetExtensionSystem()
{
- StringListPrefMember dictionaries_pref;
- dictionaries_pref.Init(spellcheck::prefs::kSpellCheckDictionaries, m_prefService.get());
- std::vector<std::string> dictionaries;
- dictionaries.reserve(languages.size());
- for (const auto &language : languages)
- dictionaries.push_back(language.toStdString());
- dictionaries_pref.SetValue(dictionaries);
+ return m_extensionSystem;
}
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
-QStringList ProfileQt::spellCheckLanguages() const
+std::string ProfileQt::GetMediaDeviceIDSalt()
{
- QStringList spellcheck_dictionaries;
- for (const auto &value : *m_prefService->GetList(spellcheck::prefs::kSpellCheckDictionaries)) {
- std::string dictionary;
- if (value.GetAsString(&dictionary))
- spellcheck_dictionaries.append(QString::fromStdString(dictionary));
- }
+ return m_prefServiceAdapter.mediaDeviceIdSalt();
+}
- return spellcheck_dictionaries;
+void ProfileQt::setupPrefService()
+{
+ // Remove previous handler before we set a new one or we will assert
+ // TODO: Remove in Qt6
+ if (m_prefServiceAdapter.prefService() != nullptr) {
+ user_prefs::UserPrefs::Remove(this);
+ m_prefServiceAdapter.commit();
+ }
+ m_prefServiceAdapter.setup(*m_profileAdapter);
+ user_prefs::UserPrefs::Set(this, m_prefServiceAdapter.prefService());
}
-void ProfileQt::setSpellCheckEnabled(bool enabled)
+PrefServiceAdapter &ProfileQt::prefServiceAdapter()
{
- m_prefService->SetBoolean(spellcheck::prefs::kSpellCheckEnable, enabled);
+ return m_prefServiceAdapter;
}
-bool ProfileQt::isSpellCheckEnabled() const
+const PrefServiceAdapter &ProfileQt::prefServiceAdapter() const
{
- return m_prefService->GetBoolean(spellcheck::prefs::kSpellCheckEnable);
+ return m_prefServiceAdapter;
}
-#endif // QT_CONFIG(webengine_spellchecker)
-#if BUILDFLAG(ENABLE_EXTENSIONS)
-extensions::ExtensionSystemQt* ProfileQt::GetExtensionSystem()
+
+content::PlatformNotificationService *ProfileQt::platformNotificationService()
{
- return m_extensionSystem;
+ if (!m_platformNotificationService)
+ m_platformNotificationService = std::make_unique<PlatformNotificationServiceQt>(this);
+ return m_platformNotificationService.get();
}
-#endif // BUILDFLAG(ENABLE_EXTENSIONS)
} // namespace QtWebEngineCore
diff --git a/src/core/profile_qt.h b/src/core/profile_qt.h
index 704c5a6e4..b6ff0a0db 100644
--- a/src/core/profile_qt.h
+++ b/src/core/profile_qt.h
@@ -45,6 +45,7 @@
#include "content/public/browser/resource_context.h"
#include "extensions/buildflags/buildflags.h"
#include "net/url_request/url_request_context.h"
+#include "pref_service_adapter.h"
#include "profile_io_data_qt.h"
#include <QtGlobal>
@@ -107,6 +108,7 @@ public:
std::vector<network::mojom::CorsOriginPatternPtr> block_patterns,
base::OnceClosure closure) override;
const content::SharedCorsOriginAccessList* GetSharedCorsOriginAccessList() const override;
+ std::string GetMediaDeviceIDSalt() override;
// Profile implementation:
PrefService *GetPrefs() override;
@@ -116,17 +118,23 @@ public:
ProfileAdapter *profileAdapter() { return m_profileAdapter; }
+ content::PlatformNotificationService *platformNotificationService();
+
#if QT_CONFIG(webengine_spellchecker)
void FailedToLoadDictionary(const std::string &language) override;
- void setSpellCheckLanguages(const QStringList &languages);
- QStringList spellCheckLanguages() const;
- void setSpellCheckEnabled(bool enabled);
- bool isSpellCheckEnabled() const;
#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
extensions::ExtensionSystemQt* GetExtensionSystem();
#endif // defined(ENABLE_EXTENSIONS)
+ // Build/Re-build the preference service. Call when updating the storage
+ // data path.
+ void setupPrefService();
+
+ PrefServiceAdapter &prefServiceAdapter();
+
+ const PrefServiceAdapter &prefServiceAdapter() const;
+
private:
friend class ContentBrowserClientQt;
friend class WebContentsAdapter;
@@ -134,10 +142,12 @@ private:
std::unique_ptr<BrowsingDataRemoverDelegateQt> m_removerDelegate;
std::unique_ptr<PermissionManagerQt> m_permissionManager;
std::unique_ptr<SSLHostStateDelegateQt> m_sslHostStateDelegate;
- std::unique_ptr<PrefService> m_prefService;
scoped_refptr<content::SharedCorsOriginAccessList> m_sharedCorsOriginAccessList;
std::unique_ptr<ProfileIODataQt> m_profileIOData;
+ std::unique_ptr<content::PlatformNotificationService> m_platformNotificationService;
ProfileAdapter *m_profileAdapter;
+ PrefServiceAdapter m_prefServiceAdapter;
+
friend class ProfileAdapter;
#if BUILDFLAG(ENABLE_EXTENSIONS)
extensions::ExtensionSystemQt *m_extensionSystem;
diff --git a/src/core/qtwebengine.gni b/src/core/qtwebengine.gni
index 11a72a2e9..d9e01a5b8 100644
--- a/src/core/qtwebengine.gni
+++ b/src/core/qtwebengine.gni
@@ -29,6 +29,7 @@ deps = [
"//components/web_cache/renderer",
"//components/spellcheck:buildflags",
"//components/proxy_config",
+ "//components/user_prefs",
"//content/public/app:browser",
"//content",
"//media:media_buildflags",
diff --git a/src/core/qtwebengine_resources.gni b/src/core/qtwebengine_resources.gni
index 4df1760da..749546741 100644
--- a/src/core/qtwebengine_resources.gni
+++ b/src/core/qtwebengine_resources.gni
@@ -24,7 +24,6 @@ repack("qtwebengine_repack_resources") {
"$root_gen_dir/chrome/browser_resources.pak",
"$root_gen_dir/chrome/common_resources.pak",
"$root_gen_dir/chrome/quota_internals_resources.pak",
- "$root_gen_dir/chrome/task_scheduler_internals_resources.pak",
"$root_gen_dir/components/components_resources.pak",
"$root_gen_dir/content/content_resources.pak",
"$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
@@ -36,7 +35,6 @@ repack("qtwebengine_repack_resources") {
deps = [
"//qtwebengine/browser:qt_webengine_resources",
"//chrome/browser/resources:quota_internals_resources",
- "//chrome/browser/resources:task_scheduler_internals_resources",
"//chrome/browser:resources_grit",
"//chrome/common:resources_grit",
"//components/resources:components_resources_grit",
diff --git a/src/core/qtwebengine_sources.gni b/src/core/qtwebengine_sources.gni
index 58df7096b..8441ca095 100644
--- a/src/core/qtwebengine_sources.gni
+++ b/src/core/qtwebengine_sources.gni
@@ -23,6 +23,8 @@ source_set("qtwebengine_spellcheck_sources") {
"//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h",
"//chrome/browser/spellchecker/spellcheck_service.cc",
"//chrome/browser/spellchecker/spellcheck_service.h",
+ "//components/language/core/browser/pref_names.cc",
+ "//components/language/core/browser/pref_names.h",
]
deps = [
"//components/spellcheck/browser",
@@ -72,8 +74,6 @@ source_set("qtwebengine_sources") {
"//chrome/browser/ui/webui/quota_internals/quota_internals_types.h",
"//chrome/browser/ui/webui/quota_internals/quota_internals_ui.cc",
"//chrome/browser/ui/webui/quota_internals/quota_internals_ui.h",
- "//chrome/browser/ui/webui/task_scheduler_internals/task_scheduler_internals_ui.cc",
- "//chrome/browser/ui/webui/task_scheduler_internals/task_scheduler_internals_ui.h",
"//chrome/common/custom_handlers/protocol_handler.cc",
"//chrome/common/custom_handlers/protocol_handler.h",
"//chrome/common/chrome_switches.cc",
@@ -84,13 +84,12 @@ source_set("qtwebengine_sources") {
"//chrome/common/url_constants.h",
"//chrome/common/webui_url_constants.cc",
"//chrome/common/webui_url_constants.h",
- "//components/prefs/in_memory_pref_store.cc",
- "//components/prefs/in_memory_pref_store.h",
]
if (enable_extensions) {
deps += [
":qtwebengine_extensions_features",
+ "//chrome/app:generated_resources",
"//chrome/browser/resources:component_extension_resources_grit",
"//chrome/common/extensions/api",
"//chrome/common/extensions/api:extensions_features",
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 3be0c9390..c98612192 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -51,11 +51,15 @@
#include "web_contents_adapter_client.h"
#include "web_event_factory.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "components/viz/common/features.h"
+#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/surfaces/frame_sink_id_allocator.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "content/browser/compositor/surface_utils.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/common/content_switches_internal.h"
@@ -270,10 +274,13 @@ static content::ScreenInfo screenInfoFromQScreen(QScreen *screen)
RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget)
: content::RenderWidgetHostViewBase::RenderWidgetHostViewBase(widget)
+ , m_taskRunner(base::ThreadTaskRunnerHandle::Get())
, m_gestureProvider(QtGestureProviderConfig(), this)
, m_sendMotionActionDown(false)
, m_touchMotionStarted(false)
- , m_compositor(new Compositor(widget))
+ , m_enableViz(features::IsVizDisplayCompositorEnabled())
+ , m_visible(false)
+ , m_needsBeginFrames(false)
, m_loadVisuallyCommittedState(NotCommitted)
, m_adapterClient(0)
, m_imeInProgress(false)
@@ -287,14 +294,39 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget
, m_mouseWheelPhaseHandler(this)
, m_frameSinkId(host()->GetFrameSinkId())
{
- host()->SetView(this);
-
if (GetTextInputManager())
GetTextInputManager()->AddObserver(this);
const QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext();
m_imeHasHiddenTextCapability = context && context->hasCapability(QPlatformInputContext::HiddenTextCapability);
+ if (m_enableViz) {
+ m_rootLayer.reset(new ui::Layer(ui::LAYER_SOLID_COLOR));
+ m_rootLayer->SetColor(SK_ColorTRANSPARENT);
+
+ m_delegatedFrameHost.reset(new content::DelegatedFrameHost(
+ host()->GetFrameSinkId(),
+ &m_delegatedFrameHostClient,
+ true /* should_register_frame_sink_id */));
+
+ content::ImageTransportFactory *imageTransportFactory = content::ImageTransportFactory::GetInstance();
+ ui::ContextFactory *contextFactory = imageTransportFactory->GetContextFactory();
+ ui::ContextFactoryPrivate *contextFactoryPrivate = imageTransportFactory->GetContextFactoryPrivate();
+ m_uiCompositor.reset(new ui::Compositor(
+ contextFactoryPrivate->AllocateFrameSinkId(),
+ contextFactory,
+ contextFactoryPrivate,
+ m_taskRunner,
+ false /* enable_pixel_canvas */));
+ m_uiCompositor->SetAcceleratedWidget(gfx::kNullAcceleratedWidget); // null means offscreen
+ m_uiCompositor->SetRootLayer(m_rootLayer.get());
+
+ m_displayFrameSink = DisplayFrameSink::findOrCreate(m_uiCompositor->frame_sink_id());
+ m_displayFrameSink->connect(this);
+ } else {
+ m_compositor.reset(new Compositor(widget));
+ }
+
if (host()->delegate() && host()->delegate()->GetInputEventRouter())
host()->delegate()->GetInputEventRouter()->AddFrameSinkIdOwner(GetFrameSinkId(), this);
@@ -304,12 +336,22 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget
config.tap_slop = ui::GestureConfiguration::GetInstance()->max_touch_move_in_pixels_for_click();
config.enable_longpress_drag_selection = false;
m_touchSelectionController.reset(new ui::TouchSelectionController(m_touchSelectionControllerClient.get(), config));
+
+ host()->render_frame_metadata_provider()->ReportAllFrameSubmissionsForTesting(true);
+
+ // May call SetNeedsBeginFrames
+ host()->SetView(this);
}
RenderWidgetHostViewQt::~RenderWidgetHostViewQt()
{
+ m_delegate.reset();
+
QObject::disconnect(m_adapterClientDestroyedConnection);
+ if (m_enableViz)
+ m_displayFrameSink->disconnect(this);
+
if (text_input_manager_)
text_input_manager_->RemoveObserver(this);
@@ -359,7 +401,7 @@ void RenderWidgetHostViewQt::SetBounds(const gfx::Rect &windowRectInDips)
m_delegate->resize(windowRectInDips.width(), windowRectInDips.height());
}
-gfx::NativeView RenderWidgetHostViewQt::GetNativeView() const
+gfx::NativeView RenderWidgetHostViewQt::GetNativeView()
{
// gfx::NativeView is a typedef to a platform specific view
// pointer (HWND, NSView*, GtkWidget*) and other ports use
@@ -396,13 +438,15 @@ void RenderWidgetHostViewQt::Focus()
host()->Focus();
}
-bool RenderWidgetHostViewQt::HasFocus() const
+bool RenderWidgetHostViewQt::HasFocus()
{
return m_delegate->hasKeyboardFocus();
}
-bool RenderWidgetHostViewQt::IsSurfaceAvailableForCopy() const
+bool RenderWidgetHostViewQt::IsSurfaceAvailableForCopy()
{
+ if (m_enableViz)
+ return m_delegatedFrameHost->CanCopyFromCompositingSurface();
return true;
}
@@ -410,6 +454,11 @@ void RenderWidgetHostViewQt::CopyFromSurface(const gfx::Rect &src_rect,
const gfx::Size &output_size,
base::OnceCallback<void(const SkBitmap &)> callback)
{
+ if (m_enableViz) {
+ m_delegatedFrameHost->CopyFromCompositingSurface(src_rect, output_size, std::move(callback));
+ return;
+ }
+
QImage image;
if (m_delegate->copySurface(toQt(src_rect), toQt(output_size), image))
std::move(callback).Run(toSkBitmap(image));
@@ -433,13 +482,25 @@ bool RenderWidgetHostViewQt::IsShowing()
}
// Retrieve the bounds of the View, in screen coordinates.
-gfx::Rect RenderWidgetHostViewQt::GetViewBounds() const
+gfx::Rect RenderWidgetHostViewQt::GetViewBounds()
{
return m_viewRectInDips;
}
void RenderWidgetHostViewQt::UpdateBackgroundColor()
{
+ if (m_enableViz) {
+ DCHECK(GetBackgroundColor());
+ SkColor color = *GetBackgroundColor();
+ bool opaque = SkColorGetA(color) == SK_AlphaOPAQUE;
+ m_rootLayer->SetFillsBoundsOpaquely(opaque);
+ m_rootLayer->SetColor(color);
+ m_uiCompositor->SetBackgroundColor(color);
+ m_delegate->setClearColor(toQt(color));
+ host()->Send(new RenderViewObserverQt_SetBackgroundColor(host()->GetRoutingID(), color));
+ return;
+ }
+
auto color = GetBackgroundColor();
if (color) {
m_delegate->setClearColor(toQt(*color));
@@ -470,8 +531,7 @@ void RenderWidgetHostViewQt::UpdateCursor(const content::WebCursor &webCursor)
void RenderWidgetHostViewQt::DisplayCursor(const content::WebCursor &webCursor)
{
- content::CursorInfo cursorInfo;
- webCursor.GetCursorInfo(&cursorInfo);
+ const content::CursorInfo &cursorInfo = webCursor.info();
Qt::CursorShape shape = Qt::ArrowCursor;
#if defined(USE_AURA)
ui::CursorType auraType = ui::CursorType::kNull;
@@ -637,7 +697,8 @@ void RenderWidgetHostViewQt::ImeCompositionRangeChanged(const gfx::Range&, const
void RenderWidgetHostViewQt::RenderProcessGone(base::TerminationStatus terminationStatus,
int exitCode)
{
- if (m_adapterClient) {
+ // RenderProcessHost::FastShutdownIfPossible results in TERMINATION_STATUS_STILL_RUNNING
+ if (m_adapterClient && terminationStatus != base::TERMINATION_STATUS_STILL_RUNNING) {
m_adapterClient->renderProcessTerminated(
m_adapterClient->renderProcessExitStatus(terminationStatus),
exitCode);
@@ -661,17 +722,15 @@ void RenderWidgetHostViewQt::DisplayTooltipText(const base::string16 &tooltip_te
m_adapterClient->setToolTip(toQt(tooltip_text));
}
-void RenderWidgetHostViewQt::DidCreateNewRendererCompositorFrameSink(viz::mojom::CompositorFrameSinkClient *frameSink)
+void RenderWidgetHostViewQt::DidCreateNewRendererCompositorFrameSink(viz::mojom::CompositorFrameSinkClient *frameSinkClient)
{
- m_compositor->setFrameSinkClient(frameSink);
+ DCHECK(!m_enableViz);
+ m_compositor->setFrameSinkClient(frameSinkClient);
}
-void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &local_surface_id, viz::CompositorFrame frame, base::Optional<viz::HitTestRegionList>)
+void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &local_surface_id, viz::CompositorFrame frame, base::Optional<viz::HitTestRegionList> hit_test_region_list)
{
- bool scrollOffsetChanged = (m_lastScrollOffset != frame.metadata.root_scroll_offset);
- bool contentsSizeChanged = (m_lastContentsSize != frame.metadata.root_layer_size);
- m_lastScrollOffset = frame.metadata.root_scroll_offset;
- m_lastContentsSize = frame.metadata.root_layer_size;
+ DCHECK(!m_enableViz);
// Force to process swap messages
uint32_t frame_token = frame.metadata.frame_token;
@@ -680,22 +739,10 @@ void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &lo
m_compositor->submitFrame(
std::move(frame),
- base::BindOnce(&RenderWidgetHostViewQtDelegate::update, base::Unretained(m_delegate.get())));
-
- if (m_loadVisuallyCommittedState == NotCommitted) {
- m_loadVisuallyCommittedState = DidFirstCompositorFrameSwap;
- } else if (m_loadVisuallyCommittedState == DidFirstVisuallyNonEmptyPaint) {
- m_adapterClient->loadVisuallyCommitted();
- m_loadVisuallyCommittedState = NotCommitted;
- }
-
- if (scrollOffsetChanged)
- m_adapterClient->updateScrollPosition(toQt(m_lastScrollOffset));
- if (contentsSizeChanged)
- m_adapterClient->updateContentsSize(toQt(m_lastContentsSize));
+ base::BindOnce(&RenderWidgetHostViewQt::callUpdate, base::Unretained(this)));
}
-void RenderWidgetHostViewQt::GetScreenInfo(content::ScreenInfo *results) const
+void RenderWidgetHostViewQt::GetScreenInfo(content::ScreenInfo *results)
{
*results = m_screenInfo;
}
@@ -908,7 +955,7 @@ viz::ScopedSurfaceIdAllocator RenderWidgetHostViewQt::DidUpdateVisualProperties(
base::OnceCallback<void()> allocation_task =
base::BindOnce(&RenderWidgetHostViewQt::OnDidUpdateVisualPropertiesComplete,
base::Unretained(this), metadata);
- return viz::ScopedSurfaceIdAllocator(std::move(allocation_task));
+ return viz::ScopedSurfaceIdAllocator(&m_dfhLocalSurfaceIdAllocator, std::move(allocation_task));
}
void RenderWidgetHostViewQt::OnDidUpdateVisualPropertiesComplete(const cc::RenderFrameMetadata &metadata)
@@ -916,19 +963,71 @@ void RenderWidgetHostViewQt::OnDidUpdateVisualPropertiesComplete(const cc::Rende
synchronizeVisualProperties(metadata.local_surface_id_allocation);
}
+void RenderWidgetHostViewQt::OnDidFirstVisuallyNonEmptyPaint()
+{
+ if (m_loadVisuallyCommittedState == NotCommitted) {
+ m_loadVisuallyCommittedState = DidFirstVisuallyNonEmptyPaint;
+ } else if (m_loadVisuallyCommittedState == DidFirstCompositorFrameSwap) {
+ m_adapterClient->loadVisuallyCommitted();
+ m_loadVisuallyCommittedState = NotCommitted;
+ }
+}
+
+void RenderWidgetHostViewQt::scheduleUpdate()
+{
+ DCHECK(m_enableViz);
+ m_taskRunner->PostTask(
+ FROM_HERE,
+ base::BindOnce(&RenderWidgetHostViewQt::callUpdate, m_weakPtrFactory.GetWeakPtr()));
+}
+
+void RenderWidgetHostViewQt::callUpdate()
+{
+ m_delegate->update();
+
+ if (m_loadVisuallyCommittedState == NotCommitted) {
+ m_loadVisuallyCommittedState = DidFirstCompositorFrameSwap;
+ } else if (m_loadVisuallyCommittedState == DidFirstVisuallyNonEmptyPaint) {
+ m_adapterClient->loadVisuallyCommitted();
+ m_loadVisuallyCommittedState = NotCommitted;
+ }
+}
+
QSGNode *RenderWidgetHostViewQt::updatePaintNode(QSGNode *oldNode)
{
+ if (m_enableViz)
+ return m_displayFrameSink->updatePaintNode(oldNode, m_delegate.get());
return m_compositor->updatePaintNode(oldNode, m_delegate.get());
}
void RenderWidgetHostViewQt::notifyShown()
{
- host()->WasShown(false);
+ if (m_enableViz) {
+ if (m_visible)
+ return;
+ m_visible = true;
+ m_delegatedFrameHost->AttachToCompositor(m_uiCompositor.get());
+ m_delegatedFrameHost->WasShown(GetLocalSurfaceIdAllocation().local_surface_id(),
+ m_viewRectInDips.size(),
+ false /* record_presentation_time */);
+ host()->WasShown(false);
+ } else {
+ host()->WasShown(false);
+ }
}
void RenderWidgetHostViewQt::notifyHidden()
{
- host()->WasHidden();
+ if (m_enableViz) {
+ if (!m_visible)
+ return;
+ m_visible = false;
+ host()->WasHidden();
+ m_delegatedFrameHost->WasHidden();
+ m_delegatedFrameHost->DetachFromCompositor();
+ } else {
+ host()->WasHidden();
+ }
}
void RenderWidgetHostViewQt::visualPropertiesChanged()
@@ -1650,7 +1749,8 @@ void RenderWidgetHostViewQt::handleFocusEvent(QFocusEvent *ev)
void RenderWidgetHostViewQt::SetNeedsBeginFrames(bool needs_begin_frames)
{
- m_compositor->setNeedsBeginFrames(needs_begin_frames);
+ m_needsBeginFrames = needs_begin_frames;
+ UpdateNeedsBeginFramesInternal();
}
content::RenderFrameHost *RenderWidgetHostViewQt::getFocusedFrameHost()
@@ -1685,30 +1785,41 @@ ui::TextInputType RenderWidgetHostViewQt::getTextInputType() const
void RenderWidgetHostViewQt::SetWantsAnimateOnlyBeginFrames()
{
+ if (m_enableViz)
+ m_delegatedFrameHost->SetWantsAnimateOnlyBeginFrames();
}
viz::SurfaceId RenderWidgetHostViewQt::GetCurrentSurfaceId() const
{
+ if (m_enableViz)
+ return m_delegatedFrameHost->GetCurrentSurfaceId();
return viz::SurfaceId();
}
const viz::FrameSinkId &RenderWidgetHostViewQt::GetFrameSinkId() const
{
+ if (m_enableViz)
+ return m_delegatedFrameHost->frame_sink_id();
return m_frameSinkId;
}
const viz::LocalSurfaceIdAllocation &RenderWidgetHostViewQt::GetLocalSurfaceIdAllocation() const
{
- return m_localSurfaceIdAllocator.GetCurrentLocalSurfaceIdAllocation();
+ return m_dfhLocalSurfaceIdAllocator.GetCurrentLocalSurfaceIdAllocation();
}
void RenderWidgetHostViewQt::TakeFallbackContentFrom(content::RenderWidgetHostView *view)
{
DCHECK(!static_cast<RenderWidgetHostViewBase*>(view)->IsRenderWidgetHostViewChildFrame());
DCHECK(!static_cast<RenderWidgetHostViewBase*>(view)->IsRenderWidgetHostViewGuest());
- base::Optional<SkColor> color = view->GetBackgroundColor();
+ RenderWidgetHostViewQt *viewQt = static_cast<RenderWidgetHostViewQt *>(view);
+ base::Optional<SkColor> color = viewQt->GetBackgroundColor();
if (color)
SetBackgroundColor(*color);
+ if (m_enableViz) {
+ m_delegatedFrameHost->TakeFallbackContentFrom(viewQt->m_delegatedFrameHost.get());
+ host()->GetContentRenderingTimeoutFrom(viewQt->host());
+ }
}
void RenderWidgetHostViewQt::EnsureSurfaceSynchronizedForWebTest()
@@ -1735,16 +1846,53 @@ void RenderWidgetHostViewQt::OnRenderFrameMetadataChangedAfterActivation()
m_selectionEnd = metadata.selection.end;
m_touchSelectionControllerClient->UpdateClientSelectionBounds(m_selectionStart, m_selectionEnd);
}
+
+ gfx::Vector2dF scrollOffset = metadata.root_scroll_offset.value_or(gfx::Vector2dF());
+ gfx::SizeF contentsSize = metadata.root_layer_size;
+ std::swap(m_lastScrollOffset, scrollOffset);
+ std::swap(m_lastContentsSize, contentsSize);
+ if (scrollOffset != m_lastScrollOffset)
+ m_adapterClient->updateScrollPosition(toQt(m_lastScrollOffset));
+ if (contentsSize != m_lastContentsSize)
+ m_adapterClient->updateContentsSize(toQt(m_lastContentsSize));
}
void RenderWidgetHostViewQt::synchronizeVisualProperties(const base::Optional<viz::LocalSurfaceIdAllocation> &childSurfaceId)
{
if (childSurfaceId)
- m_localSurfaceIdAllocator.UpdateFromChild(*childSurfaceId);
+ m_dfhLocalSurfaceIdAllocator.UpdateFromChild(*childSurfaceId);
else
- m_localSurfaceIdAllocator.GenerateId();
+ m_dfhLocalSurfaceIdAllocator.GenerateId();
+
+ if (m_enableViz) {
+ gfx::Size viewSizeInDips = GetRequestedRendererSize();
+ gfx::Size viewSizeInPixels = GetCompositorViewportPixelSize();
+ m_rootLayer->SetBounds(gfx::Rect(gfx::Point(), viewSizeInPixels));
+ m_uiCompositorLocalSurfaceIdAllocator.GenerateId();
+ m_uiCompositor->SetScaleAndSize(
+ m_screenInfo.device_scale_factor,
+ viewSizeInPixels,
+ m_uiCompositorLocalSurfaceIdAllocator.GetCurrentLocalSurfaceIdAllocation());
+ m_delegatedFrameHost->EmbedSurface(
+ m_dfhLocalSurfaceIdAllocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id(),
+ viewSizeInDips,
+ cc::DeadlinePolicy::UseDefaultDeadline());
+ }
host()->SynchronizeVisualProperties();
}
+std::unique_ptr<content::SyntheticGestureTarget> RenderWidgetHostViewQt::CreateSyntheticGestureTarget()
+{
+ return nullptr;
+}
+
+void RenderWidgetHostViewQt::UpdateNeedsBeginFramesInternal()
+{
+ if (m_enableViz)
+ m_delegatedFrameHost->SetNeedsBeginFrames(m_needsBeginFrames);
+ else
+ m_compositor->setNeedsBeginFrames(m_needsBeginFrames);
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index 6e9ddabb9..b5f2d65bb 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -40,10 +40,11 @@
#ifndef RENDER_WIDGET_HOST_VIEW_QT_H
#define RENDER_WIDGET_HOST_VIEW_QT_H
+#include "compositor/display_frame_sink.h"
+#include "delegated_frame_host_client_qt.h"
#include "render_widget_host_view_qt_delegate.h"
#include "base/memory/weak_ptr.h"
-#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/resources/transferable_resource.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "components/viz/host/host_frame_sink_client.h"
@@ -53,7 +54,7 @@
#include "content/browser/renderer_host/text_input_manager.h"
#include "gpu/ipc/common/gpu_messages.h"
#include "ui/events/gesture_detection/filtered_gesture_provider.h"
-#include "qtwebenginecoreglobal_p.h"
+
#include <QMap>
#include <QPoint>
#include <QtGlobal>
@@ -104,6 +105,7 @@ class RenderWidgetHostViewQt
, public RenderWidgetHostViewQtDelegateClient
, public base::SupportsWeakPtr<RenderWidgetHostViewQt>
, public content::TextInputManager::Observer
+ , public DisplayConsumer
{
public:
enum LoadVisuallyCommittedState {
@@ -125,18 +127,18 @@ public:
void InitAsFullscreen(content::RenderWidgetHostView*) override;
void SetSize(const gfx::Size& size) override;
void SetBounds(const gfx::Rect&) override;
- gfx::NativeView GetNativeView() const override;
+ gfx::NativeView GetNativeView() override;
gfx::NativeViewAccessible GetNativeViewAccessible() override;
void Focus() override;
- bool HasFocus() const override;
- bool IsSurfaceAvailableForCopy() const override;
+ bool HasFocus() override;
+ bool IsSurfaceAvailableForCopy() override;
void CopyFromSurface(const gfx::Rect &src_rect,
const gfx::Size &output_size,
base::OnceCallback<void(const SkBitmap &)> callback) override;
void Show() override;
void Hide() override;
bool IsShowing() override;
- gfx::Rect GetViewBounds() const override;
+ gfx::Rect GetViewBounds() override;
void UpdateBackgroundColor() override;
bool LockMouse() override;
void UnlockMouse() override;
@@ -156,7 +158,7 @@ public:
viz::ScopedSurfaceIdAllocator DidUpdateVisualProperties(const cc::RenderFrameMetadata &metadata) override;
void OnDidUpdateVisualPropertiesComplete(const cc::RenderFrameMetadata &metadata);
- void GetScreenInfo(content::ScreenInfo* results) const override;
+ void GetScreenInfo(content::ScreenInfo *results) override;
gfx::Rect GetBoundsInRootWindow() override;
void ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, content::InputEventAckState ack_result) override;
void ClearCompositorFrame() override;
@@ -170,6 +172,7 @@ public:
uint32_t GetCaptureSequenceNumber() const override;
void ResetFallbackToFirstNavigationSurface() override;
void DidStopFlinging() override;
+ std::unique_ptr<content::SyntheticGestureTarget> CreateSyntheticGestureTarget() override;
// Overridden from ui::GestureProviderClient.
void OnGestureEvent(const ui::GestureEventData& gesture) override;
@@ -211,15 +214,20 @@ public:
void ShowDefinitionForSelection() override { QT_NOT_YET_IMPLEMENTED }
#endif // defined(OS_MACOSX)
+ void UpdateNeedsBeginFramesInternal();
// Overridden from content::BrowserAccessibilityDelegate
content::BrowserAccessibilityManager* CreateBrowserAccessibilityManager(content::BrowserAccessibilityDelegate* delegate, bool for_root_frame) override;
- LoadVisuallyCommittedState getLoadVisuallyCommittedState() const { return m_loadVisuallyCommittedState; }
- void setLoadVisuallyCommittedState(LoadVisuallyCommittedState state) { m_loadVisuallyCommittedState = state; }
+
+ // Called from WebContentsDelegateQt
+ void OnDidFirstVisuallyNonEmptyPaint();
// Overridden from content::RenderFrameMetadataProvider::Observer
void OnRenderFrameMetadataChangedAfterActivation() override;
+ // Overridden from DisplayConsumer
+ void scheduleUpdate() override;
+
gfx::SizeF lastContentsSize() const { return m_lastContentsSize; }
gfx::Vector2dF lastScrollOffset() const { return m_lastScrollOffset; }
@@ -229,6 +237,8 @@ public:
ui::TextInputType getTextInputType() const;
private:
+ friend class DelegatedFrameHostClientQt;
+
void processMotionEvent(const ui::MotionEvent &motionEvent);
void clearPreviousTouchMotionState();
QList<QTouchEvent::TouchPoint> mapTouchPointIds(const QList<QTouchEvent::TouchPoint> &inputPoints);
@@ -240,12 +250,16 @@ private:
void synchronizeVisualProperties(const base::Optional<viz::LocalSurfaceIdAllocation> &childSurfaceId);
+ void callUpdate();
+
// Geometry of the view in screen DIPs.
gfx::Rect m_viewRectInDips;
// Geometry of the window, including frame, in screen DIPs.
gfx::Rect m_windowRectInDips;
content::ScreenInfo m_screenInfo;
+ scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
+
ui::FilteredGestureProvider m_gestureProvider;
base::TimeDelta m_eventsToNowDelta;
bool m_sendMotionActionDown;
@@ -254,6 +268,14 @@ private:
QList<QTouchEvent::TouchPoint> m_previousTouchPoints;
std::unique_ptr<RenderWidgetHostViewQtDelegate> m_delegate;
+ const bool m_enableViz;
+ bool m_visible;
+ bool m_needsBeginFrames;
+ DelegatedFrameHostClientQt m_delegatedFrameHostClient{this};
+ std::unique_ptr<content::DelegatedFrameHost> m_delegatedFrameHost;
+ std::unique_ptr<ui::Layer> m_rootLayer;
+ std::unique_ptr<ui::Compositor> m_uiCompositor;
+ scoped_refptr<DisplayFrameSink> m_displayFrameSink;
std::unique_ptr<Compositor> m_compositor;
LoadVisuallyCommittedState m_loadVisuallyCommittedState;
@@ -267,7 +289,8 @@ private:
gfx::Vector2dF m_lastScrollOffset;
gfx::SizeF m_lastContentsSize;
- viz::ParentLocalSurfaceIdAllocator m_localSurfaceIdAllocator;
+ viz::ParentLocalSurfaceIdAllocator m_dfhLocalSurfaceIdAllocator;
+ viz::ParentLocalSurfaceIdAllocator m_uiCompositorLocalSurfaceIdAllocator;
uint m_imState;
int m_anchorPositionWithinSelection;
@@ -289,6 +312,8 @@ private:
std::unique_ptr<ui::TouchSelectionController> m_touchSelectionController;
gfx::SelectionBound m_selectionStart;
gfx::SelectionBound m_selectionEnd;
+
+ base::WeakPtrFactory<RenderWidgetHostViewQt> m_weakPtrFactory{this};
};
} // namespace QtWebEngineCore
diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h
index 6066284d9..4ee790ce9 100644
--- a/src/core/render_widget_host_view_qt_delegate.h
+++ b/src/core/render_widget_host_view_qt_delegate.h
@@ -65,7 +65,6 @@ class QSGTexture;
class QVariant;
class QInputMethodEvent;
-class QSGInternalImageNode;
class QSGImageNode;
QT_END_NAMESPACE
@@ -102,7 +101,6 @@ public:
virtual QWindow* window() const = 0;
virtual QSGTexture *createTextureFromImage(const QImage &) = 0;
virtual QSGLayer *createLayer() = 0;
- virtual QSGInternalImageNode *createInternalImageNode() = 0;
virtual QSGImageNode *createImageNode() = 0;
virtual QSGRectangleNode *createRectangleNode() = 0;
virtual void update() = 0;
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index 5fd4c7d65..092e6845d 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -280,33 +280,33 @@ void ContentRendererClientQt::GetNavigationErrorStringsInternal(content::RenderF
if (errorHtml) {
// Use a local error page.
int resourceId;
- base::DictionaryValue errorStrings;
const std::string locale = content::RenderThread::Get()->GetLocale();
// TODO(elproxy): We could potentially get better diagnostics here by first calling
// NetErrorHelper::GetErrorStringsForDnsProbe, but that one is harder to untangle.
- error_page::LocalizedError::GetStrings(
- error.reason(), error.domain(), error.url(), isPost,
- error.stale_copy_in_cache(), false, RenderThreadObserverQt::is_incognito_process(),
- error_page::LocalizedError::OfflineContentOnNetErrorFeatureState::kDisabled,
- false, locale, std::unique_ptr<error_page::ErrorPageParams>(), &errorStrings);
+ error_page::LocalizedError::PageState errorPageState =
+ error_page::LocalizedError::GetPageState(
+ error.reason(), error.domain(), error.url(), isPost,
+ error.stale_copy_in_cache(), false, RenderThreadObserverQt::is_incognito_process(), false,
+ false, locale, std::unique_ptr<error_page::ErrorPageParams>());
+
resourceId = IDR_NET_ERROR_HTML;
const base::StringPiece template_html(ui::ResourceBundle::GetSharedInstance().GetRawDataResource(resourceId));
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, &errorStrings, "t");
+ *errorHtml = webui::GetTemplatesHtml(template_html, &errorPageState.strings, "t");
}
}
-unsigned long long ContentRendererClientQt::VisitedLinkHash(const char *canonicalUrl, size_t length)
+uint64_t ContentRendererClientQt::VisitedLinkHash(const char *canonicalUrl, size_t length)
{
return m_visitedLinkSlave->ComputeURLFingerprint(canonicalUrl, length);
}
-bool ContentRendererClientQt::IsLinkVisited(unsigned long long linkHash)
+bool ContentRendererClientQt::IsLinkVisited(uint64_t linkHash)
{
return m_visitedLinkSlave->IsVisited(linkHash);
}
diff --git a/src/core/renderer/content_renderer_client_qt.h b/src/core/renderer/content_renderer_client_qt.h
index dd164fa3a..a13d16b5c 100644
--- a/src/core/renderer/content_renderer_client_qt.h
+++ b/src/core/renderer/content_renderer_client_qt.h
@@ -101,8 +101,8 @@ public:
int http_status,
std::string *error_html) override;
- unsigned long long VisitedLinkHash(const char *canonicalUrl, size_t length) override;
- bool IsLinkVisited(unsigned long long linkHash) override;
+ uint64_t VisitedLinkHash(const char *canonical_url, size_t length) override;
+ bool IsLinkVisited(uint64_t linkHash) override;
blink::WebPrescientNetworking* GetPrescientNetworking() override;
void AddSupportedKeySystems(std::vector<std::unique_ptr<media::KeySystemProperties>>* key_systems) override;
diff --git a/src/core/renderer/content_settings_observer_qt.cpp b/src/core/renderer/content_settings_observer_qt.cpp
index 98954eb4a..a9e89dfee 100644
--- a/src/core/renderer/content_settings_observer_qt.cpp
+++ b/src/core/renderer/content_settings_observer_qt.cpp
@@ -45,7 +45,6 @@
#include "content_settings_observer_qt.h"
#include "content/public/renderer/render_frame.h"
-#include "third_party/blink/public/platform/web_content_setting_callbacks.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/web/web_plugin_document.h"
#include "third_party/blink/public/web/web_local_frame.h"
@@ -53,7 +52,6 @@
#include "common/qt_messages.h"
-using blink::WebContentSettingCallbacks;
using blink::WebSecurityOrigin;
using blink::WebString;
@@ -115,9 +113,7 @@ void ContentSettingsObserverQt::OnDestruct()
delete this;
}
-bool ContentSettingsObserverQt::AllowDatabase(const WebString &name,
- const WebString &display_name,
- unsigned /*estimated_size*/)
+bool ContentSettingsObserverQt::AllowDatabase()
{
blink::WebFrame *frame = render_frame()->GetWebFrame();
if (IsUniqueFrame(frame))
@@ -126,21 +122,20 @@ bool ContentSettingsObserverQt::AllowDatabase(const WebString &name,
bool result = false;
Send(new QtWebEngineHostMsg_AllowDatabase(
routing_id(), url::Origin(frame->GetSecurityOrigin()).GetURL(),
- url::Origin(frame->Top()->GetSecurityOrigin()).GetURL(), name.Utf16(),
- display_name.Utf16(), &result));
+ url::Origin(frame->Top()->GetSecurityOrigin()).GetURL(),
+ &result));
return result;
}
-void ContentSettingsObserverQt::RequestFileSystemAccessAsync(const WebContentSettingCallbacks &callbacks)
+void ContentSettingsObserverQt::RequestFileSystemAccessAsync(base::OnceCallback<void(bool)> callback)
{
blink::WebFrame *frame = render_frame()->GetWebFrame();
if (IsUniqueFrame(frame)) {
- WebContentSettingCallbacks permissionCallbacks(callbacks);
- permissionCallbacks.DoDeny();
+ std::move(callback).Run(false);
return;
}
++m_currentRequestId;
- bool inserted = m_permissionRequests.insert(std::make_pair(m_currentRequestId, callbacks)).second;
+ bool inserted = m_permissionRequests.insert(std::make_pair(m_currentRequestId, std::move(callback))).second;
// Verify there are no duplicate insertions.
DCHECK(inserted);
@@ -190,14 +185,10 @@ void ContentSettingsObserverQt::OnRequestFileSystemAccessAsyncResponse(int reque
if (it == m_permissionRequests.end())
return;
- WebContentSettingCallbacks callbacks = it->second;
+ base::OnceCallback<void(bool)> callback = std::move(it->second);
m_permissionRequests.erase(it);
- if (allowed) {
- callbacks.DoAllow();
- return;
- }
- callbacks.DoDeny();
+ std::move(callback).Run(allowed);
}
void ContentSettingsObserverQt::ClearBlockedContentSettings()
diff --git a/src/core/renderer/content_settings_observer_qt.h b/src/core/renderer/content_settings_observer_qt.h
index 69b0eda9e..9c071aa3c 100644
--- a/src/core/renderer/content_settings_observer_qt.h
+++ b/src/core/renderer/content_settings_observer_qt.h
@@ -51,7 +51,6 @@
#include "url/gurl.h"
namespace blink {
-class WebContentSettingCallbacks;
class WebSecurityOrigin;
}
@@ -68,10 +67,8 @@ public:
~ContentSettingsObserverQt() override;
// blink::WebContentSettingsClient:
- bool AllowDatabase(const blink::WebString &name,
- const blink::WebString &display_name,
- unsigned estimated_size) override;
- void RequestFileSystemAccessAsync(const blink::WebContentSettingCallbacks &callbacks) override;
+ bool AllowDatabase() override;
+ void RequestFileSystemAccessAsync(base::OnceCallback<void(bool)> callback) override;
bool AllowIndexedDB(const blink::WebSecurityOrigin &origin) override;
bool AllowStorage(bool local) override;
@@ -94,7 +91,7 @@ private:
base::flat_map<StoragePermissionsKey, bool> m_cachedStoragePermissions;
int m_currentRequestId;
- base::flat_map<int, blink::WebContentSettingCallbacks> m_permissionRequests;
+ base::flat_map<int, base::OnceCallback<void(bool)>> m_permissionRequests;
DISALLOW_COPY_AND_ASSIGN(ContentSettingsObserverQt);
};
diff --git a/src/core/renderer/web_channel_ipc_transport.cpp b/src/core/renderer/web_channel_ipc_transport.cpp
index 3b9c17b6a..745fe8b1e 100644
--- a/src/core/renderer/web_channel_ipc_transport.cpp
+++ b/src/core/renderer/web_channel_ipc_transport.cpp
@@ -214,9 +214,11 @@ void WebChannelIPCTransport::ResetWorldId()
void WebChannelIPCTransport::DispatchWebChannelMessage(const std::vector<uint8_t> &binaryJson, uint32_t worldId)
{
- DCHECK(m_canUseContext);
DCHECK(m_worldId == worldId);
+ if (!m_canUseContext)
+ return;
+
QJsonDocument doc = QJsonDocument::fromRawData(reinterpret_cast<const char *>(binaryJson.data()),
binaryJson.size(), QJsonDocument::BypassValidation);
DCHECK(doc.isObject());
diff --git a/src/core/renderer_host/resource_dispatcher_host_delegate_qt.cpp b/src/core/renderer_host/resource_dispatcher_host_delegate_qt.cpp
index 36c5e6ed1..eba835cd7 100644
--- a/src/core/renderer_host/resource_dispatcher_host_delegate_qt.cpp
+++ b/src/core/renderer_host/resource_dispatcher_host_delegate_qt.cpp
@@ -120,7 +120,7 @@ bool ResourceDispatcherHostDelegateQt::ShouldInterceptResourceAsStream(net::URLR
GURL *origin,
std::string *payload)
{
- const content::ResourceRequestInfo* info =
+ content::ResourceRequestInfo* info =
content::ResourceRequestInfo::ForRequest(request);
int render_process_host_id = -1;
@@ -162,7 +162,7 @@ bool ResourceDispatcherHostDelegateQt::ShouldInterceptResourceAsStream(net::URLR
void ResourceDispatcherHostDelegateQt::OnStreamCreated(net::URLRequest *request,
std::unique_ptr<content::StreamInfo> stream)
{
- const content::ResourceRequestInfo *info = content::ResourceRequestInfo::ForRequest(request);
+ content::ResourceRequestInfo *info = content::ResourceRequestInfo::ForRequest(request);
std::map<net::URLRequest *, StreamTargetInfo>::iterator ix = stream_target_info_.find(request);
CHECK(ix != stream_target_info_.end());
int render_frame_id = -1;
diff --git a/src/core/type_conversion.cpp b/src/core/type_conversion.cpp
index 02d2db448..ddadeb9f2 100644
--- a/src/core/type_conversion.cpp
+++ b/src/core/type_conversion.cpp
@@ -40,11 +40,14 @@
#include "type_conversion.h"
#include <content/public/common/favicon_url.h>
+#include <net/cert/x509_certificate.h>
+#include <net/cert/x509_util.h>
#include <ui/events/event_constants.h>
#include <ui/gfx/image/image_skia.h>
#include <QtCore/qcoreapplication.h>
#include <QtGui/qmatrix4x4.h>
+#include <QtNetwork/qsslcertificate.h>
namespace QtWebEngineCore {
@@ -256,4 +259,20 @@ void convertToQt(const SkMatrix44 &m, QMatrix4x4 &c)
c = qtMatrix;
}
+static QSslCertificate toCertificate(CRYPTO_BUFFER *buffer)
+{
+ auto derCert = net::x509_util::CryptoBufferAsStringPiece(buffer);
+ return QSslCertificate(QByteArray::fromRawData(derCert.data(), derCert.size()), QSsl::Der);
+}
+
+QList<QSslCertificate> toCertificateChain(net::X509Certificate *certificate)
+{
+ // from leaf to root as in QtNetwork
+ QList<QSslCertificate> chain;
+ chain.append(toCertificate(certificate->cert_buffer()));
+ for (auto &&buffer : certificate->intermediate_buffers())
+ chain.append(toCertificate(buffer.get()));
+ return chain;
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h
index 7b1f1b4d6..dfd8e8fef 100644
--- a/src/core/type_conversion.h
+++ b/src/core/type_conversion.h
@@ -64,6 +64,7 @@
#include "url/gurl.h"
QT_FORWARD_DECLARE_CLASS(QMatrix4x4)
+QT_FORWARD_DECLARE_CLASS(QSslCertificate)
namespace content {
struct FaviconURL;
@@ -73,6 +74,10 @@ namespace gfx {
class ImageSkiaRep;
}
+namespace net {
+class X509Certificate;
+}
+
namespace QtWebEngineCore {
inline QString toQt(const base::string16 &string)
@@ -291,6 +296,8 @@ inline QStringList fromVector(const std::vector<base::string16> &vector)
FaviconInfo toFaviconInfo(const content::FaviconURL &);
+QList<QSslCertificate> toCertificateChain(net::X509Certificate *certificate);
+
} // namespace QtWebEngineCore
#endif // TYPE_CONVERSION_H
diff --git a/src/core/user_notification_controller.cpp b/src/core/user_notification_controller.cpp
index d169bf854..50d12e8fd 100644
--- a/src/core/user_notification_controller.cpp
+++ b/src/core/user_notification_controller.cpp
@@ -51,14 +51,14 @@
namespace QtWebEngineCore {
-static Qt::LayoutDirection toDirection(blink::PlatformNotificationData::Direction direction)
+static Qt::LayoutDirection toDirection(blink::mojom::NotificationDirection direction)
{
switch (direction) {
- case blink::PlatformNotificationData::DIRECTION_LEFT_TO_RIGHT:
+ case blink::mojom::NotificationDirection::LEFT_TO_RIGHT:
return Qt::LeftToRight;
- case blink::PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT:
+ case blink::mojom::NotificationDirection::RIGHT_TO_LEFT:
return Qt::RightToLeft;
- case blink::PlatformNotificationData::DIRECTION_AUTO:
+ case blink::mojom::NotificationDirection::AUTO:
default:
break;
}
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index ca2479965..85e63c5a4 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -61,9 +61,10 @@
#include "web_engine_settings.h"
#include "base/command_line.h"
-#include "base/message_loop/message_loop_impl.h"
#include "base/run_loop.h"
#include "base/task/post_task.h"
+#include "base/task/sequence_manager/sequence_manager_impl.h"
+#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
#include "base/values.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -81,13 +82,10 @@
#include "content/public/common/drop_data.h"
#include "content/public/common/page_state.h"
#include "content/public/common/page_zoom.h"
-#include "content/public/common/renderer_preferences.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/web_preferences.h"
#include "content/public/common/webrtc_ip_handling_policy.h"
#include "extensions/buildflags/buildflags.h"
-#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h"
-//#include "third_party/blink/public/web/web_find_options.h"
#include "third_party/blink/public/web/web_media_player_action.h"
#include "printing/buildflags/buildflags.h"
#include "ui/base/clipboard/clipboard.h"
@@ -214,10 +212,10 @@ static QVariant fromJSValue(const base::Value *result)
return ret;
}
-static void callbackOnEvaluateJS(WebContentsAdapterClient *adapterClient, quint64 requestId, const base::Value *result)
+static void callbackOnEvaluateJS(WebContentsAdapterClient *adapterClient, quint64 requestId, base::Value result)
{
if (requestId)
- adapterClient->didRunJavaScript(requestId, fromJSValue(result));
+ adapterClient->didRunJavaScript(requestId, fromJSValue(&result));
}
#if QT_CONFIG(webengine_printing_and_pdf)
@@ -417,7 +415,6 @@ WebContentsAdapter::WebContentsAdapter()
#endif
, m_adapterClient(nullptr)
, m_nextRequestId(CallbackDirectory::ReservedCallbackIdsEnd)
- , m_lastFindRequestId(0)
, m_currentDropAction(blink::kWebDragOperationNone)
, m_devToolsFrontend(nullptr)
{
@@ -434,7 +431,6 @@ WebContentsAdapter::WebContentsAdapter(std::unique_ptr<content::WebContents> web
#endif
, m_adapterClient(nullptr)
, m_nextRequestId(CallbackDirectory::ReservedCallbackIdsEnd)
- , m_lastFindRequestId(0)
, m_currentDropAction(blink::kWebDragOperationNone)
, m_devToolsFrontend(nullptr)
{
@@ -478,32 +474,7 @@ void WebContentsAdapter::initialize(content::SiteInstance *site)
m_webContents = content::WebContents::Create(create_params);
}
- content::RendererPreferences* rendererPrefs = m_webContents->GetMutableRendererPrefs();
- rendererPrefs->use_custom_colors = true;
- // Qt returns a flash time (the whole cycle) in ms, chromium expects just the interval in seconds
- const int qtCursorFlashTime = QGuiApplication::styleHints()->cursorFlashTime();
- rendererPrefs->caret_blink_interval = base::TimeDelta::FromMillisecondsD(0.5 * static_cast<double>(qtCursorFlashTime));
- rendererPrefs->user_agent_override = m_profileAdapter->httpUserAgent().toStdString();
- rendererPrefs->accept_languages = m_profileAdapter->httpAcceptLanguageWithoutQualities().toStdString();
-#if QT_CONFIG(webengine_webrtc)
- base::CommandLine* commandLine = base::CommandLine::ForCurrentProcess();
- if (commandLine->HasSwitch(switches::kForceWebRtcIPHandlingPolicy))
- rendererPrefs->webrtc_ip_handling_policy = commandLine->GetSwitchValueASCII(switches::kForceWebRtcIPHandlingPolicy);
- else
- rendererPrefs->webrtc_ip_handling_policy = m_adapterClient->webEngineSettings()->testAttribute(WebEngineSettings::WebRTCPublicInterfacesOnly)
- ? content::kWebRTCIPHandlingDefaultPublicInterfaceOnly
- : content::kWebRTCIPHandlingDefault;
-#endif
- // Set web-contents font settings to the default font settings as Chromium constantly overrides
- // the global font defaults with the font settings of the latest web-contents created.
- static const gfx::FontRenderParams params = gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr);
- rendererPrefs->should_antialias_text = params.antialiasing;
- rendererPrefs->use_subpixel_positioning = params.subpixel_positioning;
- rendererPrefs->hinting = params.hinting;
- rendererPrefs->use_autohinter = params.autohinter;
- rendererPrefs->use_bitmaps = params.use_bitmaps;
- rendererPrefs->subpixel_rendering = params.subpixel_rendering;
- m_webContents->GetRenderViewHost()->SyncRendererPrefs();
+ initializeRenderPrefs();
// Create and attach observers to the WebContents.
m_webContentsDelegate.reset(new WebContentsDelegateQt(m_webContents.get(), m_adapterClient));
@@ -540,6 +511,40 @@ void WebContentsAdapter::initialize(content::SiteInstance *site)
m_adapterClient->initializationFinished();
}
+void WebContentsAdapter::initializeRenderPrefs()
+{
+ blink::mojom::RendererPreferences *rendererPrefs = m_webContents->GetMutableRendererPrefs();
+ rendererPrefs->use_custom_colors = true;
+ // Qt returns a flash time (the whole cycle) in ms, chromium expects just the interval in
+ // seconds
+ const int qtCursorFlashTime = QGuiApplication::styleHints()->cursorFlashTime();
+ rendererPrefs->caret_blink_interval =
+ base::TimeDelta::FromMillisecondsD(0.5 * static_cast<double>(qtCursorFlashTime));
+ rendererPrefs->user_agent_override = m_profileAdapter->httpUserAgent().toStdString();
+ rendererPrefs->accept_languages = m_profileAdapter->httpAcceptLanguageWithoutQualities().toStdString();
+#if QT_CONFIG(webengine_webrtc)
+ base::CommandLine* commandLine = base::CommandLine::ForCurrentProcess();
+ if (commandLine->HasSwitch(switches::kForceWebRtcIPHandlingPolicy))
+ rendererPrefs->webrtc_ip_handling_policy =
+ commandLine->GetSwitchValueASCII(switches::kForceWebRtcIPHandlingPolicy);
+ else
+ rendererPrefs->webrtc_ip_handling_policy =
+ m_adapterClient->webEngineSettings()->testAttribute(WebEngineSettings::WebRTCPublicInterfacesOnly)
+ ? content::kWebRTCIPHandlingDefaultPublicInterfaceOnly
+ : content::kWebRTCIPHandlingDefault;
+#endif
+ // Set web-contents font settings to the default font settings as Chromium constantly overrides
+ // the global font defaults with the font settings of the latest web-contents created.
+ static const gfx::FontRenderParams params = gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr);
+ rendererPrefs->should_antialias_text = params.antialiasing;
+ rendererPrefs->use_subpixel_positioning = params.subpixel_positioning;
+ rendererPrefs->hinting = params.hinting;
+ rendererPrefs->use_autohinter = params.autohinter;
+ rendererPrefs->use_bitmaps = params.use_bitmaps;
+ rendererPrefs->subpixel_rendering = params.subpixel_rendering;
+ m_webContents->GetRenderViewHost()->SyncRendererPrefs();
+}
+
bool WebContentsAdapter::canGoBack() const
{
CHECK_INITIALIZED(false);
@@ -552,6 +557,12 @@ bool WebContentsAdapter::canGoForward() const
return m_webContents->GetController().CanGoForward();
}
+bool WebContentsAdapter::canGoToOffset(int offset) const
+{
+ CHECK_INITIALIZED(false);
+ return m_webContents->GetController().CanGoToOffset(offset);
+}
+
void WebContentsAdapter::stop()
{
CHECK_INITIALIZED();
@@ -568,16 +579,22 @@ void WebContentsAdapter::stop()
void WebContentsAdapter::reload()
{
CHECK_INITIALIZED();
+ bool wasDiscarded = (m_lifecycleState == LifecycleState::Discarded);
+ setLifecycleState(LifecycleState::Active);
CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
- m_webContents->GetController().Reload(content::ReloadType::NORMAL, /*checkRepost = */false);
+ if (!wasDiscarded) // undiscard() already triggers a reload
+ m_webContents->GetController().Reload(content::ReloadType::NORMAL, /*checkRepost = */false);
focusIfNecessary();
}
void WebContentsAdapter::reloadAndBypassCache()
{
CHECK_INITIALIZED();
+ bool wasDiscarded = (m_lifecycleState == LifecycleState::Discarded);
+ setLifecycleState(LifecycleState::Active);
CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
- m_webContents->GetController().Reload(content::ReloadType::BYPASSING_CACHE, /*checkRepost = */false);
+ if (!wasDiscarded) // undiscard() already triggers a reload
+ m_webContents->GetController().Reload(content::ReloadType::BYPASSING_CACHE, /*checkRepost = */false);
focusIfNecessary();
}
@@ -600,6 +617,8 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
scoped_refptr<content::SiteInstance> site =
content::SiteInstance::CreateForURL(m_profileAdapter->profile(), gurl);
initialize(site.get());
+ } else {
+ setLifecycleState(LifecycleState::Active);
}
CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
@@ -672,7 +691,7 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
}
auto navigate = [](QWeakPointer<WebContentsAdapter> weakAdapter, const content::NavigationController::LoadURLParams &params) {
- WebContentsAdapter *adapter = weakAdapter.data();
+ const auto adapter = weakAdapter.toStrongRef();
if (!adapter)
return;
adapter->webContents()->GetController().LoadURLWithParams(params);
@@ -695,6 +714,8 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT
{
if (!isInitialized())
loadDefault();
+ else
+ setLifecycleState(LifecycleState::Active);
CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
@@ -831,6 +852,26 @@ void WebContentsAdapter::unselect()
m_webContents->CollapseSelection();
}
+void WebContentsAdapter::navigateBack()
+{
+ CHECK_INITIALIZED();
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
+ if (!m_webContents->GetController().CanGoBack())
+ return;
+ m_webContents->GetController().GoBack();
+ focusIfNecessary();
+}
+
+void WebContentsAdapter::navigateForward()
+{
+ CHECK_INITIALIZED();
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost());
+ if (!m_webContents->GetController().CanGoForward())
+ return;
+ m_webContents->GetController().GoForward();
+ focusIfNecessary();
+}
+
void WebContentsAdapter::navigateToIndex(int offset)
{
CHECK_INITIALIZED();
@@ -964,13 +1005,14 @@ void WebContentsAdapter::runJavaScript(const QString &javaScript, quint32 worldI
CHECK_INITIALIZED();
content::RenderViewHost *rvh = m_webContents->GetRenderViewHost();
Q_ASSERT(rvh);
+// static_cast<content::RenderFrameHostImpl *>(rvh->GetMainFrame())->NotifyUserActivation();
if (worldId == 0) {
- rvh->GetMainFrame()->ExecuteJavaScript(toString16(javaScript));
+ rvh->GetMainFrame()->ExecuteJavaScript(toString16(javaScript), base::NullCallback());
return;
}
- content::RenderFrameHost::JavaScriptResultCallback callback = base::Bind(&callbackOnEvaluateJS, m_adapterClient, CallbackDirectory::NoCallbackId);
- rvh->GetMainFrame()->ExecuteJavaScriptInIsolatedWorld(toString16(javaScript), callback, worldId);
+ content::RenderFrameHost::JavaScriptResultCallback callback = base::BindOnce(&callbackOnEvaluateJS, m_adapterClient, CallbackDirectory::NoCallbackId);
+ rvh->GetMainFrame()->ExecuteJavaScriptInIsolatedWorld(toString16(javaScript), std::move(callback), worldId);
}
quint64 WebContentsAdapter::runJavaScriptCallbackResult(const QString &javaScript, quint32 worldId)
@@ -978,11 +1020,12 @@ quint64 WebContentsAdapter::runJavaScriptCallbackResult(const QString &javaScrip
CHECK_INITIALIZED(0);
content::RenderViewHost *rvh = m_webContents->GetRenderViewHost();
Q_ASSERT(rvh);
- content::RenderFrameHost::JavaScriptResultCallback callback = base::Bind(&callbackOnEvaluateJS, m_adapterClient, m_nextRequestId);
+// static_cast<content::RenderFrameHostImpl *>(rvh->GetMainFrame())->NotifyUserActivation();
+ content::RenderFrameHost::JavaScriptResultCallback callback = base::BindOnce(&callbackOnEvaluateJS, m_adapterClient, m_nextRequestId);
if (worldId == 0)
- rvh->GetMainFrame()->ExecuteJavaScript(toString16(javaScript), callback);
+ rvh->GetMainFrame()->ExecuteJavaScript(toString16(javaScript), std::move(callback));
else
- rvh->GetMainFrame()->ExecuteJavaScriptInIsolatedWorld(toString16(javaScript), callback, worldId);
+ rvh->GetMainFrame()->ExecuteJavaScriptInIsolatedWorld(toString16(javaScript), std::move(callback), worldId);
return m_nextRequestId++;
}
@@ -1000,41 +1043,6 @@ quint64 WebContentsAdapter::fetchDocumentInnerText()
return m_nextRequestId++;
}
-quint64 WebContentsAdapter::findText(const QString &subString, bool caseSensitively, bool findBackward)
-{
- CHECK_INITIALIZED(0);
- if (m_lastFindRequestId > m_webContentsDelegate->lastReceivedFindReply()) {
- // There are cases where the render process will overwrite a previous request
- // with the new search and we'll have a dangling callback, leaving the application
- // waiting for it forever.
- // Assume that any unfinished find has been unsuccessful when a new one is started
- // to cover that case.
- m_webContentsDelegate->setLastReceivedFindReply(m_lastFindRequestId);
- m_adapterClient->didFindText(m_lastFindRequestId, 0);
- }
-
- blink::mojom::FindOptionsPtr options = blink::mojom::FindOptions::New();
- options->forward = !findBackward;
- options->match_case = caseSensitively;
- options->find_next = subString == m_webContentsDelegate->lastSearchedString();
- m_webContentsDelegate->setLastSearchedString(subString);
-
- // Find already allows a request ID as input, but only as an int.
- // Use the same counter but mod it to MAX_INT, this keeps the same likeliness of request ID clashing.
- int shrunkRequestId = m_nextRequestId++ & 0x7fffffff;
- m_webContents->Find(shrunkRequestId, toString16(subString), std::move(options));
- m_lastFindRequestId = shrunkRequestId;
- return shrunkRequestId;
-}
-
-void WebContentsAdapter::stopFinding()
-{
- CHECK_INITIALIZED();
- m_webContentsDelegate->setLastReceivedFindReply(m_lastFindRequestId);
- m_webContentsDelegate->setLastSearchedString(QString());
- m_webContents->StopFinding(content::STOP_FIND_ACTION_KEEP_SELECTION);
-}
-
void WebContentsAdapter::updateWebPreferences(const content::WebPreferences & webPreferences)
{
CHECK_INITIALIZED();
@@ -1112,7 +1120,7 @@ void WebContentsAdapter::setAudioMuted(bool muted)
m_webContents->SetAudioMuted(muted);
}
-bool WebContentsAdapter::recentlyAudible()
+bool WebContentsAdapter::recentlyAudible() const
{
CHECK_INITIALIZED(false);
return m_webContents->IsCurrentlyAudible();
@@ -1173,6 +1181,18 @@ bool WebContentsAdapter::hasInspector() const
return false;
}
+bool WebContentsAdapter::isInspector() const
+{
+ return m_inspector;
+}
+
+void WebContentsAdapter::setInspector(bool inspector)
+{
+ m_inspector = inspector;
+ if (inspector)
+ setLifecycleState(LifecycleState::Active);
+}
+
void WebContentsAdapter::openDevToolsFrontend(QSharedPointer<WebContentsAdapter> frontendAdapter)
{
Q_ASSERT(isInitialized());
@@ -1185,7 +1205,10 @@ void WebContentsAdapter::openDevToolsFrontend(QSharedPointer<WebContentsAdapter>
m_devToolsFrontend->Close();
}
+ setLifecycleState(LifecycleState::Active);
+
m_devToolsFrontend = DevToolsFrontendQt::Show(frontendAdapter, m_webContents.get());
+ updateRecommendedState();
}
void WebContentsAdapter::closeDevToolsFrontend()
@@ -1201,6 +1224,7 @@ void WebContentsAdapter::devToolsFrontendDestroyed(DevToolsFrontendQt *frontend)
Q_ASSERT(frontend == m_devToolsFrontend);
Q_UNUSED(frontend);
m_devToolsFrontend = nullptr;
+ updateRecommendedState();
}
void WebContentsAdapter::exitFullScreen()
@@ -1568,7 +1592,11 @@ void WebContentsAdapter::waitForUpdateDragActionCalled()
const qint64 timeout = 3000;
QElapsedTimer t;
t.start();
- base::MessagePump::Delegate *delegate = static_cast<base::MessageLoopImpl *>(base::MessageLoopCurrent::Get().ToMessageLoopBaseDeprecated());
+ auto seqMan = base::MessageLoopCurrent::GetCurrentSequenceManagerImpl();
+ base::MessagePump::Delegate *delegate =
+ static_cast<base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl *>(
+ seqMan->controller_.get());
+
DCHECK(delegate);
m_updateDragActionCalled = false;
for (;;) {
@@ -1630,12 +1658,6 @@ void WebContentsAdapter::focusIfNecessary()
m_webContents->Focus();
}
-bool WebContentsAdapter::isFindTextInProgress() const
-{
- CHECK_INITIALIZED(false);
- return m_lastFindRequestId != m_webContentsDelegate->lastReceivedFindReply();
-}
-
bool WebContentsAdapter::hasFocusedFrame() const
{
CHECK_INITIALIZED(false);
@@ -1666,8 +1688,7 @@ WebContentsAdapterClient::renderProcessExitStatus(int terminationStatus) {
break;
case base::TERMINATION_STATUS_STILL_RUNNING:
case base::TERMINATION_STATUS_MAX_ENUM:
- // should be unreachable since Chromium asserts status != TERMINATION_STATUS_STILL_RUNNING
- // before calling this method
+ Q_UNREACHABLE();
break;
}
@@ -1680,6 +1701,12 @@ FaviconManager *WebContentsAdapter::faviconManager()
return m_webContentsDelegate->faviconManager();
}
+FindTextHelper *WebContentsAdapter::findTextHelper()
+{
+ CHECK_INITIALIZED(nullptr);
+ return m_webContentsDelegate->findTextHelper();
+}
+
void WebContentsAdapter::viewSource()
{
CHECK_INITIALIZED();
@@ -1692,6 +1719,230 @@ bool WebContentsAdapter::canViewSource()
return m_webContents->GetController().CanViewSource();
}
+WebContentsAdapter::LifecycleState WebContentsAdapter::lifecycleState() const
+{
+ return m_lifecycleState;
+}
+
+void WebContentsAdapter::setLifecycleState(LifecycleState state)
+{
+ CHECK_INITIALIZED();
+
+ LifecycleState from = m_lifecycleState;
+ LifecycleState to = state;
+
+ const auto warn = [from, to](const char *reason) {
+ static const char *names[] { "Active", "Frozen", "Discarded" };
+ qWarning("setLifecycleState: failed to transition from %s to %s state: %s",
+ names[(int)from], names[(int)to], reason);
+ };
+
+ if (from == to)
+ return;
+
+ if (from == LifecycleState::Active) {
+ if (isVisible()) {
+ warn("page is visible");
+ return;
+ }
+ if (hasInspector() || isInspector()) {
+ warn("DevTools open");
+ return;
+ }
+ }
+
+ if (from == LifecycleState::Discarded && to != LifecycleState::Active) {
+ warn("illegal transition");
+ return;
+ }
+
+ // Prevent recursion due to initializationFinished() in undiscard().
+ m_lifecycleState = to;
+
+ switch (to) {
+ case LifecycleState::Active:
+ if (from == LifecycleState::Frozen)
+ unfreeze();
+ else
+ undiscard();
+ break;
+ case LifecycleState::Frozen:
+ freeze();
+ break;
+ case LifecycleState::Discarded:
+ discard();
+ break;
+ }
+
+ m_adapterClient->lifecycleStateChanged(to);
+ updateRecommendedState();
+}
+
+WebContentsAdapter::LifecycleState WebContentsAdapter::recommendedState() const
+{
+ return m_recommendedState;
+}
+
+WebContentsAdapter::LifecycleState WebContentsAdapter::determineRecommendedState() const
+{
+ CHECK_INITIALIZED(LifecycleState::Active);
+
+ if (m_lifecycleState == LifecycleState::Discarded)
+ return LifecycleState::Discarded;
+
+ if (isVisible())
+ return LifecycleState::Active;
+
+ if (m_webContentsDelegate->loadingState() != WebContentsDelegateQt::LoadingState::Loaded)
+ return LifecycleState::Active;
+
+ if (recentlyAudible())
+ return LifecycleState::Active;
+
+ if (m_webContents->GetSiteInstance()->GetRelatedActiveContentsCount() > 1U)
+ return LifecycleState::Active;
+
+ if (hasInspector() || isInspector())
+ return LifecycleState::Active;
+
+ if (m_webContentsDelegate->isCapturingAudio() || m_webContentsDelegate->isCapturingVideo()
+ || m_webContentsDelegate->isMirroring() || m_webContentsDelegate->isCapturingDesktop())
+ return LifecycleState::Active;
+
+ if (m_webContents->IsCrashed())
+ return LifecycleState::Active;
+
+ if (m_lifecycleState == LifecycleState::Active)
+ return LifecycleState::Frozen;
+
+ // Form input is not saved.
+ if (m_webContents->GetPageImportanceSignals().had_form_interaction)
+ return LifecycleState::Frozen;
+
+ // Do not discard PDFs as they might contain entry that is not saved and they
+ // don't remember their scrolling positions. See crbug.com/547286 and
+ // crbug.com/65244.
+ if (m_webContents->GetContentsMimeType() == "application/pdf")
+ return LifecycleState::Frozen;
+
+ return LifecycleState::Discarded;
+}
+
+void WebContentsAdapter::updateRecommendedState()
+{
+ LifecycleState newState = determineRecommendedState();
+ if (m_recommendedState == newState)
+ return;
+
+ m_recommendedState = newState;
+ m_adapterClient->recommendedStateChanged(newState);
+}
+
+bool WebContentsAdapter::isVisible() const
+{
+ CHECK_INITIALIZED(false);
+
+ // Visibility::OCCLUDED is not used
+ return m_webContents->GetVisibility() == content::Visibility::VISIBLE;
+}
+
+void WebContentsAdapter::setVisible(bool visible)
+{
+ CHECK_INITIALIZED();
+
+ if (isVisible() == visible)
+ return;
+
+ if (visible) {
+ setLifecycleState(LifecycleState::Active);
+ wasShown();
+ } else {
+ Q_ASSERT(m_lifecycleState == LifecycleState::Active);
+ wasHidden();
+ }
+
+ m_adapterClient->visibleChanged(visible);
+ updateRecommendedState();
+}
+
+void WebContentsAdapter::freeze()
+{
+ m_webContents->SetPageFrozen(true);
+}
+
+void WebContentsAdapter::unfreeze()
+{
+ m_webContents->SetPageFrozen(false);
+}
+
+void WebContentsAdapter::discard()
+{
+ // Based on TabLifecycleUnitSource::TabLifecycleUnit::FinishDiscard
+
+ if (m_webContents->IsLoading()) {
+ m_webContentsDelegate->didFailLoad(m_webContentsDelegate->url(), net::Error::ERR_ABORTED,
+ QStringLiteral("Discarded"));
+ }
+
+ content::WebContents::CreateParams createParams(m_profileAdapter->profile());
+ createParams.initially_hidden = true;
+ createParams.desired_renderer_state = content::WebContents::CreateParams::kNoRendererProcess;
+ createParams.last_active_time = m_webContents->GetLastActiveTime();
+ std::unique_ptr<content::WebContents> nullContents = content::WebContents::Create(createParams);
+ std::unique_ptr<WebContentsDelegateQt> nullDelegate(new WebContentsDelegateQt(nullContents.get(), m_adapterClient));
+ nullContents->GetController().CopyStateFrom(&m_webContents->GetController(),
+ /* needs_reload */ false);
+ nullDelegate->copyStateFrom(m_webContentsDelegate.get());
+ nullContents->SetWasDiscarded(true);
+
+ // Kill render process if this is the only page it's got.
+ content::RenderProcessHost *renderProcessHost = m_webContents->GetMainFrame()->GetProcess();
+ renderProcessHost->FastShutdownIfPossible(/* page_count */ 1u,
+ /* skip_unload_handlers */ false);
+
+#if QT_CONFIG(webengine_webchannel)
+ if (m_webChannel)
+ m_webChannel->disconnectFrom(m_webChannelTransport.get());
+ m_webChannelTransport.reset();
+ m_webChannel = nullptr;
+ m_webChannelWorld = 0;
+#endif
+ m_renderViewObserverHost.reset();
+ m_webContentsDelegate.reset();
+ m_webContents.reset();
+
+ m_webContents = std::move(nullContents);
+ initializeRenderPrefs();
+ m_webContentsDelegate = std::move(nullDelegate);
+ m_renderViewObserverHost.reset(new RenderViewObserverHostQt(m_webContents.get(), m_adapterClient));
+ WebContentsViewQt *contentsView =
+ static_cast<WebContentsViewQt *>(static_cast<content::WebContentsImpl *>(m_webContents.get())->GetView());
+ contentsView->setClient(m_adapterClient);
+#if QT_CONFIG(webengine_printing_and_pdf)
+ PrintViewManagerQt::CreateForWebContents(webContents());
+#endif
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ extensions::ExtensionWebContentsObserverQt::CreateForWebContents(webContents());
+#endif
+}
+
+void WebContentsAdapter::undiscard()
+{
+ m_webContents->GetController().SetNeedsReload();
+ m_webContents->GetController().LoadIfNecessary();
+ // Create a RenderView with the initial empty document
+ content::RenderViewHost *rvh = m_webContents->GetRenderViewHost();
+ Q_ASSERT(rvh);
+ if (!rvh->IsRenderViewLive())
+ static_cast<content::WebContentsImpl *>(m_webContents.get())
+ ->CreateRenderViewForRenderManager(rvh, MSG_ROUTING_NONE, MSG_ROUTING_NONE,
+ base::UnguessableToken::Create(),
+ content::FrameReplicationState());
+ m_webContentsDelegate->RenderViewHostChanged(nullptr, rvh);
+ m_adapterClient->initializationFinished();
+ m_adapterClient->selectionChanged();
+}
+
ASSERT_ENUMS_MATCH(WebContentsAdapterClient::UnknownDisposition, WindowOpenDisposition::UNKNOWN)
ASSERT_ENUMS_MATCH(WebContentsAdapterClient::CurrentTabDisposition, WindowOpenDisposition::CURRENT_TAB)
ASSERT_ENUMS_MATCH(WebContentsAdapterClient::SingletonTabDisposition, WindowOpenDisposition::SINGLETON_TAB)
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index da4bc9190..11f8f9cb1 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -85,6 +85,7 @@ namespace QtWebEngineCore {
class DevToolsFrontendQt;
class FaviconManager;
+class FindTextHelper;
class MessagePassingInterface;
class ProfileQt;
class RenderViewObserverHostQt;
@@ -109,8 +110,17 @@ public:
void load(const QWebEngineHttpRequest &request);
void setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl);
+ using LifecycleState = WebContentsAdapterClient::LifecycleState;
+ LifecycleState lifecycleState() const;
+ void setLifecycleState(LifecycleState state);
+ LifecycleState recommendedState() const;
+
+ bool isVisible() const;
+ void setVisible(bool visible);
+
bool canGoBack() const;
bool canGoForward() const;
+ bool canGoToOffset(int) const;
void stop();
void reload();
void reloadAndBypassCache();
@@ -130,6 +140,8 @@ public:
void selectAll();
void unselect();
+ void navigateBack();
+ void navigateForward();
void navigateToIndex(int);
void navigateToOffset(int);
int navigationEntryCount();
@@ -147,15 +159,13 @@ public:
quint64 runJavaScriptCallbackResult(const QString &javaScript, quint32 worldId);
quint64 fetchDocumentMarkup();
quint64 fetchDocumentInnerText();
- quint64 findText(const QString &subString, bool caseSensitively, bool findBackward);
- void stopFinding();
void updateWebPreferences(const content::WebPreferences &webPreferences);
void download(const QUrl &url, const QString &suggestedFileName,
const QUrl &referrerUrl = QUrl(),
ReferrerPolicy referrerPolicy = ReferrerPolicy::Default);
bool isAudioMuted() const;
void setAudioMuted(bool mute);
- bool recentlyAudible();
+ bool recentlyAudible() const;
// Must match blink::WebMediaPlayerAction::Type.
enum MediaPlayerAction {
@@ -171,6 +181,8 @@ public:
void inspectElementAt(const QPoint &location);
bool hasInspector() const;
+ bool isInspector() const;
+ void setInspector(bool inspector);
void exitFullScreen();
void requestClose();
void changedFullScreen();
@@ -178,8 +190,6 @@ public:
void closeDevToolsFrontend();
void devToolsFrontendDestroyed(DevToolsFrontendQt *frontend);
- void wasShown();
- void wasHidden();
void grantMediaAccessPermission(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags flags);
void runGeolocationRequestCallback(const QUrl &securityOrigin, bool allowed);
void grantMouseLockPermission(bool granted);
@@ -194,6 +204,7 @@ public:
void setWebChannel(QWebChannel *, uint worldId);
#endif
FaviconManager *faviconManager();
+ FindTextHelper *findTextHelper();
QPointF lastScrollOffset() const;
QSizeF lastContentsSize() const;
@@ -222,12 +233,25 @@ public:
// meant to be used within WebEngineCore only
void initialize(content::SiteInstance *site);
content::WebContents *webContents() const;
+ void updateRecommendedState();
private:
Q_DISABLE_COPY(WebContentsAdapter)
void waitForUpdateDragActionCalled();
bool handleDropDataFileContents(const content::DropData &dropData, QMimeData *mimeData);
+ void wasShown();
+ void wasHidden();
+
+ LifecycleState determineRecommendedState() const;
+
+ void freeze();
+ void unfreeze();
+ void discard();
+ void undiscard();
+
+ void initializeRenderPrefs();
+
ProfileAdapter *m_profileAdapter;
std::unique_ptr<content::WebContents> m_webContents;
std::unique_ptr<WebContentsDelegateQt> m_webContentsDelegate;
@@ -239,7 +263,6 @@ private:
#endif
WebContentsAdapterClient *m_adapterClient;
quint64 m_nextRequestId;
- int m_lastFindRequestId;
std::unique_ptr<content::DropData> m_currentDropData;
uint m_currentDropAction;
bool m_updateDragActionCalled;
@@ -247,6 +270,9 @@ private:
QPointF m_lastDragScreenPos;
std::unique_ptr<QTemporaryDir> m_dndTmpDir;
DevToolsFrontendQt *m_devToolsFrontend;
+ LifecycleState m_lifecycleState = LifecycleState::Active;
+ LifecycleState m_recommendedState = LifecycleState::Active;
+ bool m_inspector = false;
};
} // namespace QtWebEngineCore
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 540dd5f1f..4bdb55b4c 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -64,6 +64,7 @@ QT_FORWARD_DECLARE_CLASS(CertificateErrorController)
QT_FORWARD_DECLARE_CLASS(ClientCertSelectController)
QT_FORWARD_DECLARE_CLASS(QKeyEvent)
QT_FORWARD_DECLARE_CLASS(QVariant)
+QT_FORWARD_DECLARE_CLASS(QWebEngineFindTextResult)
QT_FORWARD_DECLARE_CLASS(QWebEngineQuotaRequest)
QT_FORWARD_DECLARE_CLASS(QWebEngineRegisterProtocolHandlerRequest)
QT_FORWARD_DECLARE_CLASS(QWebEngineUrlRequestInfo)
@@ -381,7 +382,8 @@ public:
FormSubmittedNavigation,
BackForwardNavigation,
ReloadNavigation,
- OtherNavigation
+ OtherNavigation,
+ RedirectNavigation,
};
enum JavaScriptConsoleMessageLevel {
@@ -411,11 +413,26 @@ public:
};
Q_DECLARE_FLAGS(MediaRequestFlags, MediaRequestFlag)
+ enum class LifecycleState {
+ Active,
+ Frozen,
+ Discarded,
+ };
+
+ enum class LoadingState {
+ Unloaded,
+ Loading,
+ Loaded,
+ };
+
virtual ~WebContentsAdapterClient() { }
virtual RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client) = 0;
virtual RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegateForPopup(RenderWidgetHostViewQtDelegateClient *client) = 0;
virtual void initializationFinished() = 0;
+ virtual void lifecycleStateChanged(LifecycleState) = 0;
+ virtual void recommendedStateChanged(LifecycleState) = 0;
+ virtual void visibleChanged(bool) = 0;
virtual void titleChanged(const QString&) = 0;
virtual void urlChanged(const QUrl&) = 0;
virtual void iconChanged(const QUrl&) = 0;
@@ -445,7 +462,6 @@ public:
virtual void didRunJavaScript(quint64 requestId, const QVariant& result) = 0;
virtual void didFetchDocumentMarkup(quint64 requestId, const QString& result) = 0;
virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) = 0;
- virtual void didFindText(quint64 requestId, int matchCount) = 0;
virtual void didPrintPage(quint64 requestId, QSharedPointer<QByteArray>) = 0;
virtual void didPrintPageToPdf(const QString &filePath, bool success) = 0;
virtual bool passOnFocus(bool reverse) = 0;
@@ -483,6 +499,7 @@ public:
virtual TouchHandleDrawableClient *createTouchHandle(const QMap<int, QImage> &images) = 0;
virtual void showTouchSelectionMenu(TouchSelectionMenuController *menuController, const QRect &bounds, const QSize &handleSize) = 0;
virtual void hideTouchSelectionMenu() = 0;
+ virtual void findTextFinished(const QWebEngineFindTextResult &result) = 0;
virtual ProfileAdapter *profileAdapter() = 0;
virtual WebContentsAdapter* webContentsAdapter() = 0;
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 7719e78d7..9855e3859 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -102,9 +102,11 @@ static WebContentsAdapterClient::JavaScriptConsoleMessageLevel mapToJavascriptCo
WebContentsDelegateQt::WebContentsDelegateQt(content::WebContents *webContents, WebContentsAdapterClient *adapterClient)
: m_viewClient(adapterClient)
- , m_lastReceivedFindReply(0)
, m_faviconManager(new FaviconManager(webContents, adapterClient))
+ , m_findTextHelper(new FindTextHelper(webContents, adapterClient))
, m_lastLoadProgress(-1)
+ , m_loadingState(determineLoadingState(webContents))
+ , m_didStartLoadingSeen(m_loadingState == LoadingState::Loading)
, m_frameFocusedObserver(adapterClient)
{
webContents->SetDelegate(this);
@@ -280,6 +282,18 @@ void WebContentsDelegateQt::RenderFrameDeleted(content::RenderFrameHost *render_
m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID());
}
+void WebContentsDelegateQt::RenderProcessGone(base::TerminationStatus status)
+{
+ // Based one TabLoadTracker::RenderProcessGone
+
+ if (status == base::TerminationStatus::TERMINATION_STATUS_NORMAL_TERMINATION
+ || status == base::TerminationStatus::TERMINATION_STATUS_STILL_RUNNING) {
+ return;
+ }
+
+ setLoadingState(LoadingState::Unloaded);
+}
+
void WebContentsDelegateQt::RenderFrameHostChanged(content::RenderFrameHost *old_host, content::RenderFrameHost *new_host)
{
if (old_host) {
@@ -336,9 +350,7 @@ void WebContentsDelegateQt::EmitLoadFinished(bool success, const QUrl &url, bool
void WebContentsDelegateQt::EmitLoadCommitted()
{
- // Make sure that we don't set the findNext WebFindOptions on a new frame.
- m_lastSearchedString = QString();
-
+ m_findTextHelper->handleLoadCommitted();
m_viewClient->loadCommitted();
m_viewClient->updateNavigationActions();
}
@@ -380,6 +392,46 @@ void WebContentsDelegateQt::DidFinishNavigation(content::NavigationHandle *navig
}
}
+void WebContentsDelegateQt::DidStartLoading()
+{
+ // Based on TabLoadTracker::DidStartLoading
+
+ if (!web_contents()->IsLoadingToDifferentDocument())
+ return;
+ if (m_loadingState == LoadingState::Loading) {
+ DCHECK(m_didStartLoadingSeen);
+ return;
+ }
+ m_didStartLoadingSeen = true;
+}
+
+void WebContentsDelegateQt::DidReceiveResponse()
+{
+ // Based on TabLoadTracker::DidReceiveResponse
+
+ if (m_loadingState == LoadingState::Loading) {
+ DCHECK(m_didStartLoadingSeen);
+ return;
+ }
+
+ // A transition to loading requires both DidStartLoading (navigation
+ // committed) and DidReceiveResponse (data has been transmitted over the
+ // network) events to occur. This is because NavigationThrottles can block
+ // actual network requests, but not the rest of the state machinery.
+ if (m_didStartLoadingSeen)
+ setLoadingState(LoadingState::Loading);
+}
+
+void WebContentsDelegateQt::DidStopLoading()
+{
+ // Based on TabLoadTracker::DidStopLoading
+
+ // NOTE: PageAlmostIdle feature not implemented
+
+ if (m_loadingState == LoadingState::Loading)
+ setLoadingState(LoadingState::Loaded);
+}
+
void WebContentsDelegateQt::didFailLoad(const QUrl &url, int errorCode, const QString &errorDescription)
{
m_viewClient->iconChanged(QUrl());
@@ -388,6 +440,9 @@ void WebContentsDelegateQt::didFailLoad(const QUrl &url, int errorCode, const QS
void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code, const base::string16& error_description)
{
+ if (m_loadingState == LoadingState::Loading)
+ setLoadingState(LoadingState::Loaded);
+
if (render_frame_host != web_contents()->GetMainFrame())
return;
@@ -520,13 +575,7 @@ bool WebContentsDelegateQt::DidAddMessageToConsole(content::WebContents *source,
void WebContentsDelegateQt::FindReply(content::WebContents *source, int request_id, int number_of_matches, const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update)
{
- Q_UNUSED(source)
- Q_UNUSED(selection_rect)
- Q_UNUSED(active_match_ordinal)
- if (final_update && request_id > m_lastReceivedFindReply) {
- m_lastReceivedFindReply = request_id;
- m_viewClient->didFindText(request_id, number_of_matches);
- }
+ m_findTextHelper->handleFindReply(source, request_id, number_of_matches, selection_rect, active_match_ordinal, final_update);
}
void WebContentsDelegateQt::RequestMediaAccessPermission(content::WebContents *web_contents, const content::MediaStreamRequest &request, content::MediaResponseCallback callback)
@@ -566,13 +615,7 @@ void WebContentsDelegateQt::DidFirstVisuallyNonEmptyPaint()
if (!rwhv)
return;
- RenderWidgetHostViewQt::LoadVisuallyCommittedState loadVisuallyCommittedState = rwhv->getLoadVisuallyCommittedState();
- if (loadVisuallyCommittedState == RenderWidgetHostViewQt::NotCommitted) {
- rwhv->setLoadVisuallyCommittedState(RenderWidgetHostViewQt::DidFirstVisuallyNonEmptyPaint);
- } else if (loadVisuallyCommittedState == RenderWidgetHostViewQt::DidFirstCompositorFrameSwap) {
- m_viewClient->loadVisuallyCommitted();
- rwhv->setLoadVisuallyCommittedState(RenderWidgetHostViewQt::NotCommitted);
- }
+ rwhv->OnDidFirstVisuallyNonEmptyPaint();
}
void WebContentsDelegateQt::ActivateContents(content::WebContents* contents)
@@ -741,6 +784,11 @@ FaviconManager *WebContentsDelegateQt::faviconManager()
return m_faviconManager.data();
}
+FindTextHelper *WebContentsDelegateQt::findTextHelper()
+{
+ return m_findTextHelper.data();
+}
+
WebEngineSettings *WebContentsDelegateQt::webEngineSettings() const {
return m_viewClient->webEngineSettings();
}
@@ -750,6 +798,82 @@ WebContentsAdapter *WebContentsDelegateQt::webContentsAdapter() const
return m_viewClient->webContentsAdapter();
}
+void WebContentsDelegateQt::copyStateFrom(WebContentsDelegateQt *source)
+{
+ m_url = source->m_url;
+ m_title = source->m_title;
+ NavigationStateChanged(web_contents(), content::INVALIDATE_TYPE_URL);
+ m_faviconManager->copyStateFrom(source->m_faviconManager.data());
+}
+
+WebContentsDelegateQt::LoadingState WebContentsDelegateQt::determineLoadingState(content::WebContents *contents)
+{
+ // Based on TabLoadTracker::DetermineLoadingState
+
+ if (contents->IsLoadingToDifferentDocument() && !contents->IsWaitingForResponse())
+ return LoadingState::Loading;
+
+ content::NavigationController &controller = contents->GetController();
+ if (controller.GetLastCommittedEntry() != nullptr && !controller.IsInitialNavigation() && !controller.NeedsReload())
+ return LoadingState::Loaded;
+
+ return LoadingState::Unloaded;
+}
+
+void WebContentsDelegateQt::setLoadingState(LoadingState state)
+{
+ if (m_loadingState == state)
+ return;
+
+ m_loadingState = state;
+
+ webContentsAdapter()->updateRecommendedState();
+}
+
+int &WebContentsDelegateQt::streamCount(blink::MediaStreamType type)
+{
+ // Based on MediaStreamCaptureIndicator::WebContentsDeviceUsage::GetStreamCount
+ switch (type) {
+ case blink::MEDIA_DEVICE_AUDIO_CAPTURE:
+ return m_audioStreamCount;
+
+ case blink::MEDIA_DEVICE_VIDEO_CAPTURE:
+ return m_videoStreamCount;
+
+ case blink::MEDIA_GUM_TAB_AUDIO_CAPTURE:
+ case blink::MEDIA_GUM_TAB_VIDEO_CAPTURE:
+ return m_mirroringStreamCount;
+
+ case blink::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE:
+ case blink::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE:
+ case blink::MEDIA_DISPLAY_VIDEO_CAPTURE:
+ case blink::MEDIA_DISPLAY_AUDIO_CAPTURE:
+ return m_desktopStreamCount;
+
+ case blink::MEDIA_NO_SERVICE:
+ case blink::NUM_MEDIA_TYPES:
+ NOTREACHED();
+ return m_videoStreamCount;
+ }
+ NOTREACHED();
+ return m_videoStreamCount;
+}
+
+void WebContentsDelegateQt::addDevices(const blink::MediaStreamDevices &devices)
+{
+ for (const auto &device : devices)
+ ++streamCount(device.type);
+
+ webContentsAdapter()->updateRecommendedState();
+}
+
+void WebContentsDelegateQt::removeDevices(const blink::MediaStreamDevices &devices)
+{
+ for (const auto &device : devices)
+ ++streamCount(device.type);
+
+ webContentsAdapter()->updateRecommendedState();
+}
FrameFocusedObserver::FrameFocusedObserver(WebContentsAdapterClient *adapterClient)
: m_viewClient(adapterClient)
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 9a3afebed..f1d5ed76c 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -41,6 +41,7 @@
#define WEB_CONTENTS_DELEGATE_QT_H
#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/public/browser/media_capture_devices.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "third_party/skia/include/core/SkColor.h"
@@ -49,6 +50,7 @@
#include "color_chooser_controller.h"
#include "favicon_manager.h"
+#include "find_text_helper.h"
#include "javascript_dialog_manager_qt.h"
#include <QtCore/qvector.h>
@@ -111,10 +113,6 @@ class WebContentsDelegateQt : public content::WebContentsDelegate
public:
WebContentsDelegateQt(content::WebContents*, WebContentsAdapterClient *adapterClient);
~WebContentsDelegateQt();
- QString lastSearchedString() const { return m_lastSearchedString; }
- void setLastSearchedString(const QString &s) { m_lastSearchedString = s; }
- int lastReceivedFindReply() const { return m_lastReceivedFindReply; }
- void setLastReceivedFindReply(int id) { m_lastReceivedFindReply = id; }
QUrl url() const { return m_url; }
QString title() const { return m_title; }
@@ -153,10 +151,14 @@ public:
// WebContentsObserver overrides
void RenderFrameCreated(content::RenderFrameHost *render_frame_host) override;
void RenderFrameDeleted(content::RenderFrameHost *render_frame_host) override;
+ void RenderProcessGone(base::TerminationStatus status) override;
void RenderFrameHostChanged(content::RenderFrameHost *old_host, content::RenderFrameHost *new_host) override;
void RenderViewHostChanged(content::RenderViewHost *old_host, content::RenderViewHost *new_host) override;
void DidStartNavigation(content::NavigationHandle *navigation_handle) override;
void DidFinishNavigation(content::NavigationHandle *navigation_handle) override;
+ void DidStartLoading() override;
+ void DidReceiveResponse() override;
+ void DidStopLoading() override;
void DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code, const base::string16& error_description) override;
void DidFinishLoad(content::RenderFrameHost *render_frame_host, const GURL &validated_url) override;
void BeforeUnloadFired(bool proceed, const base::TimeTicks& proceed_time) override;
@@ -173,6 +175,7 @@ public:
void requestUserNotificationPermission(const QUrl &requestingOrigin);
void launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame, bool has_user_gesture);
FaviconManager *faviconManager();
+ FindTextHelper *findTextHelper();
void setSavePageInfo(const SavePageInfo &spi) { m_savePageInfo = spi; }
const SavePageInfo &savePageInfo() { return m_savePageInfo; }
@@ -181,25 +184,52 @@ public:
WebContentsAdapter *webContentsAdapter() const;
WebContentsAdapterClient *adapterClient() const { return m_viewClient; }
+ void copyStateFrom(WebContentsDelegateQt *source);
+
+ using LoadingState = WebContentsAdapterClient::LoadingState;
+ LoadingState loadingState() const { return m_loadingState; }
+
+ void addDevices(const blink::MediaStreamDevices &devices);
+ void removeDevices(const blink::MediaStreamDevices &devices);
+
+ bool isCapturingAudio() const { return m_audioStreamCount > 0; }
+ bool isCapturingVideo() const { return m_videoStreamCount > 0; }
+ bool isMirroring() const { return m_mirroringStreamCount > 0; }
+ bool isCapturingDesktop() const { return m_desktopStreamCount > 0; }
+
+ base::WeakPtr<WebContentsDelegateQt> AsWeakPtr() { return m_weakPtrFactory.GetWeakPtr(); }
+
private:
QWeakPointer<WebContentsAdapter> createWindow(std::unique_ptr<content::WebContents> new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture);
void EmitLoadStarted(const QUrl &url, bool isErrorPage = false);
void EmitLoadFinished(bool success, const QUrl &url, bool isErrorPage = false, int errorCode = 0, const QString &errorDescription = QString());
void EmitLoadCommitted();
+ LoadingState determineLoadingState(content::WebContents *contents);
+ void setLoadingState(LoadingState state);
+
+ int &streamCount(blink::MediaStreamType type);
+
WebContentsAdapterClient *m_viewClient;
- QString m_lastSearchedString;
- int m_lastReceivedFindReply;
QVector<int64_t> m_loadingErrorFrameList;
QScopedPointer<FaviconManager> m_faviconManager;
+ QScopedPointer<FindTextHelper> m_findTextHelper;
SavePageInfo m_savePageInfo;
QSharedPointer<FilePickerController> m_filePickerController;
QUrl m_initialTargetUrl;
int m_lastLoadProgress;
+ LoadingState m_loadingState;
+ bool m_didStartLoadingSeen;
FrameFocusedObserver m_frameFocusedObserver;
QUrl m_url;
QString m_title;
+ int m_audioStreamCount = 0;
+ int m_videoStreamCount = 0;
+ int m_mirroringStreamCount = 0;
+ int m_desktopStreamCount = 0;
+
+ base::WeakPtrFactory<WebContentsDelegateQt> m_weakPtrFactory { this };
};
} // namespace QtWebEngineCore
diff --git a/src/core/web_contents_view_qt.h b/src/core/web_contents_view_qt.h
index ec09f9aae..978a2ce2e 100644
--- a/src/core/web_contents_view_qt.h
+++ b/src/core/web_contents_view_qt.h
@@ -111,8 +111,7 @@ public:
void FocusThroughTabTraversal(bool reverse) override;
#if defined(OS_MACOSX)
- void CloseTabAfterEventTracking() override { QT_NOT_YET_IMPLEMENTED }
- bool IsEventTracking() const override { QT_NOT_YET_IMPLEMENTED; return false; }
+ bool CloseTabAfterEventTrackingIfNeeded() override { QT_NOT_YET_IMPLEMENTED return false; }
#endif // defined(OS_MACOSX)
// content::RenderViewHostDelegateView overrides:
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index a3a5881bf..a42565c2b 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -44,9 +44,9 @@
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
-#include "base/message_loop/message_loop_impl.h"
#include "base/run_loop.h"
#include "base/task/post_task.h"
+#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
#include "base/threading/thread_restrictions.h"
#include "cc/base/switches.h"
#if QT_CONFIG(webengine_printing_and_pdf)
@@ -74,12 +74,15 @@
#include "gpu/command_buffer/service/sync_point_manager.h"
#include "gpu/ipc/host/gpu_switches.h"
#include "media/audio/audio_manager.h"
+#include "media/base/media_switches.h"
#include "mojo/core/embedder/embedder.h"
#include "net/base/port_util.h"
#include "ppapi/buildflags/buildflags.h"
+#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/network_switches.h"
#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h"
#include "services/service_manager/sandbox/switches.h"
+#include "third_party/blink/public/common/features.h"
#include "ui/events/event_switches.h"
#include "ui/native_theme/native_theme_features.h"
#include "ui/gl/gl_switches.h"
@@ -241,7 +244,8 @@ void WebEngineContext::destroy()
destroyGpuProcess();
base::MessagePump::Delegate *delegate =
- static_cast<base::MessageLoopImpl *>(m_runLoop->delegate_);
+ static_cast<base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl *>(
+ m_runLoop->delegate_);
// Flush the UI message loop before quitting.
while (delegate->DoWork()) { }
@@ -386,7 +390,7 @@ WebEngineContext::WebEngineContext()
: m_mainDelegate(new ContentMainDelegateQt)
, m_globalQObject(new QObject())
{
- base::TaskScheduler::Create("Browser");
+ base::ThreadPool::Create("Browser");
m_contentRunner.reset(content::ContentMainRunner::Create());
m_browserRunner = content::BrowserMainRunner::Create();
@@ -484,6 +488,16 @@ WebEngineContext::WebEngineContext()
parsedCommandLine->AppendSwitch(switches::kDisableES3GLContext);
#endif
+ bool threadedGpu = true;
+#ifndef QT_NO_OPENGL
+ threadedGpu = QOpenGLContext::supportsThreadedOpenGL();
+#endif
+
+ bool enableViz = ((threadedGpu && !parsedCommandLine->HasSwitch("disable-viz-display-compositor"))
+ || parsedCommandLine->HasSwitch("enable-viz-display-compositor"));
+ parsedCommandLine->RemoveSwitch("disable-viz-display-compositor");
+ parsedCommandLine->RemoveSwitch("enable-viz-display-compositor");
+
std::string disableFeatures;
std::string enableFeatures;
// Needed to allow navigations within pages that were set using setHtml(). One example is
@@ -491,31 +505,45 @@ WebEngineContext::WebEngineContext()
// This is deprecated behavior, and will be removed in a future Chromium version, as per
// upstream Chromium commit ba52f56207a4b9d70b34880fbff2352e71a06422.
appendToFeatureList(enableFeatures, features::kAllowContentInitiatedDataUrlNavigations.name);
- // Surface synchronization breaks our current graphics integration (since 65)
- appendToFeatureList(disableFeatures, features::kEnableSurfaceSynchronization.name);
- // Viz Display Compositor is enabled by default since 73. Doesn't work for us (also implies SurfaceSynchronization)
- appendToFeatureList(disableFeatures, features::kVizDisplayCompositor.name);
// The video-capture service is not functioning at this moment (since 69)
appendToFeatureList(disableFeatures, features::kMojoVideoCapture.name);
// Breaks WebEngineNewViewRequest.userInitiated API (since 73)
appendToFeatureList(disableFeatures, features::kUserActivationV2.name);
- appendToFeatureList(disableFeatures, features::kBackgroundFetch.name);
+ // We do not yet support the network-service, but it is enabled by default since 75.
+ appendToFeatureList(disableFeatures, network::features::kNetworkService.name);
+ // BlinkGenPropertyTrees is enabled by default in 75, but causes regressions.
+ appendToFeatureList(disableFeatures, blink::features::kBlinkGenPropertyTrees.name);
#if QT_CONFIG(webengine_printing_and_pdf)
appendToFeatureList(disableFeatures, printing::features::kUsePdfCompositorServiceForPrint.name);
#endif
+ // Explicitly tell Chromium about default-on features we do not support
+ appendToFeatureList(disableFeatures, features::kBackgroundFetch.name);
+ appendToFeatureList(disableFeatures, features::kOriginTrials.name);
+ appendToFeatureList(disableFeatures, features::kWebAuth.name);
+ appendToFeatureList(disableFeatures, features::kWebAuthCable.name);
+ appendToFeatureList(disableFeatures, features::kWebPayments.name);
+ appendToFeatureList(disableFeatures, features::kWebUsb.name);
+
if (useEmbeddedSwitches) {
// embedded switches are based on the switches for Android, see content/browser/android/content_startup_flags.cc
appendToFeatureList(enableFeatures, features::kOverlayScrollbar.name);
- if (!parsedCommandLine->HasSwitch(switches::kDisablePinch))
- parsedCommandLine->AppendSwitch(switches::kEnablePinch);
parsedCommandLine->AppendSwitch(switches::kEnableViewport);
parsedCommandLine->AppendSwitch(switches::kMainFrameResizesAreOrientationChanges);
parsedCommandLine->AppendSwitch(cc::switches::kDisableCompositedAntialiasing);
}
+ if (!enableViz) {
+ // Surface synchronization breaks our current graphics integration (since 65)
+ appendToFeatureList(disableFeatures, features::kEnableSurfaceSynchronization.name);
+ // Viz Display Compositor is enabled by default since 73. Doesn't work for us (also implies SurfaceSynchronization)
+ appendToFeatureList(disableFeatures, features::kVizDisplayCompositor.name);
+ // VideoSurfaceLayer is enabled by default since 75. We don't support it.
+ appendToFeatureList(disableFeatures, media::kUseSurfaceLayerForVideo.name);
+ }
+
appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, disableFeatures);
appendToFeatureSwitch(parsedCommandLine, switches::kEnableFeatures, enableFeatures);
base::FeatureList::InitializeInstance(
@@ -604,19 +632,10 @@ WebEngineContext::WebEngineContext()
parsedCommandLine->AppendSwitch(switches::kDisableGpu);
}
- bool threadedGpu = true;
-#ifndef QT_NO_OPENGL
- threadedGpu = QOpenGLContext::supportsThreadedOpenGL();
-#endif
registerMainThreadFactories(threadedGpu);
SetContentClient(new ContentClientQt);
- content::StartBrowserTaskScheduler();
- content::BrowserTaskExecutor::Create();
-
- mojo::core::Init();
-
content::ContentMainParams contentMainParams(m_mainDelegate.get());
#if defined(OS_WIN)
sandbox::SandboxInterfaceInfo sandbox_info = {0};
@@ -624,12 +643,24 @@ WebEngineContext::WebEngineContext()
contentMainParams.sandbox_info = &sandbox_info;
#endif
m_contentRunner->Initialize(contentMainParams);
- m_browserRunner->Initialize(content::MainFunctionParams(*base::CommandLine::ForCurrentProcess()));
+
+ mojo::core::Init();
+
+ // This block mirrors ContentMainRunnerImpl::RunServiceManager():
+ m_mainDelegate->PreCreateMainMessageLoop();
+ base::MessageLoop::InitMessagePumpForUIFactory(messagePumpFactory);
+ content::BrowserTaskExecutor::Create();
+ m_mainDelegate->PostEarlyInitialization(false);
+ content::StartBrowserThreadPool();
+ content::BrowserTaskExecutor::PostFeatureListSetup();
// Once the MessageLoop has been created, attach a top-level RunLoop.
m_runLoop.reset(new base::RunLoop);
m_runLoop->BeforeRun();
+ content::MainFunctionParams mainParams(*base::CommandLine::ForCurrentProcess());
+ m_browserRunner->Initialize(mainParams);
+
m_devtoolsServer.reset(new DevToolsServerQt());
m_devtoolsServer->start();
// Force the initialization of MediaCaptureDevicesDispatcher on the UI
diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp
index b6250a65f..9bc1279ba 100644
--- a/src/core/web_engine_settings.cpp
+++ b/src/core/web_engine_settings.cpp
@@ -49,10 +49,10 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
-#include "content/public/common/renderer_preferences.h"
#include "content/public/common/web_preferences.h"
-#include "media/base/media_switches.h"
#include "content/public/common/webrtc_ip_handling_policy.h"
+#include "media/base/media_switches.h"
+#include "third_party/blink/public/mojom/renderer_preferences.mojom.h"
#include "ui/events/event_switches.h"
#include <QFont>
@@ -401,7 +401,7 @@ void WebEngineSettings::applySettingsToWebPreferences(content::WebPreferences *p
prefs->default_encoding = defaultTextEncoding().toStdString();
}
-bool WebEngineSettings::applySettingsToRendererPreferences(content::RendererPreferences *prefs)
+bool WebEngineSettings::applySettingsToRendererPreferences(blink::mojom::RendererPreferences *prefs)
{
bool changed = false;
#if QT_CONFIG(webengine_webrtc)
diff --git a/src/core/web_engine_settings.h b/src/core/web_engine_settings.h
index b2a45098a..95eea669f 100644
--- a/src/core/web_engine_settings.h
+++ b/src/core/web_engine_settings.h
@@ -60,10 +60,14 @@
#include <QTimer>
namespace content {
-struct RendererPreferences;
class WebContents;
struct WebPreferences;
}
+namespace blink {
+namespace mojom {
+class RendererPreferences;
+}
+}
namespace QtWebEngineCore {
class WebContentsAdapter;
@@ -169,7 +173,7 @@ public:
private:
void doApply();
void applySettingsToWebPreferences(content::WebPreferences *);
- bool applySettingsToRendererPreferences(content::RendererPreferences *);
+ bool applySettingsToRendererPreferences(blink::mojom::RendererPreferences *);
void setWebContentsAdapter(WebContentsAdapter *adapter) { m_adapter = adapter; }
WebContentsAdapter* m_adapter;
diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp
index a0fac73ec..3598c1c78 100644
--- a/src/core/web_event_factory.cpp
+++ b/src/core/web_event_factory.cpp
@@ -92,24 +92,24 @@ static KeyboardDriver keyboardDriverImpl()
{
QString platformName = QGuiApplication::platformName();
- if (platformName == QLatin1Literal("windows"))
+ if (platformName == QLatin1String("windows"))
return KeyboardDriver::Windows;
- if (platformName == QLatin1Literal("cocoa"))
+ if (platformName == QLatin1String("cocoa"))
return KeyboardDriver::Cocoa;
- if (platformName == QLatin1Literal("xcb") || platformName == QLatin1Literal("wayland"))
+ if (platformName == QLatin1String("xcb") || platformName == QLatin1String("wayland"))
return KeyboardDriver::Xkb;
#if QT_CONFIG(libinput)
// Based on QEglFSIntegration::createInputHandlers and QLibInputKeyboard::processKey.
- if (platformName == QLatin1Literal("eglfs") && !qEnvironmentVariableIntValue("QT_QPA_EGLFS_NO_LIBINPUT"))
+ if (platformName == QLatin1String("eglfs") && !qEnvironmentVariableIntValue("QT_QPA_EGLFS_NO_LIBINPUT"))
return KeyboardDriver::Xkb;
#endif
#if QT_CONFIG(evdev)
// Based on QEglFSIntegration::createInputHandlers.
- if (platformName == QLatin1Literal("eglfs"))
+ if (platformName == QLatin1String("eglfs"))
return KeyboardDriver::Evdev;
#endif
@@ -1428,7 +1428,7 @@ WebGestureEvent WebEventFactory::toWebGestureEvent(QNativeGestureEvent *ev)
webKitEvent.SetPositionInScreen(WebFloatPoint(ev->screenPos().x(),
ev->screenPos().y()));
- webKitEvent.SetSourceDevice(blink::kWebGestureDeviceTouchpad);
+ webKitEvent.SetSourceDevice(blink::WebGestureDevice::kTouchpad);
Qt::NativeGestureType gestureType = ev->gestureType();
switch (gestureType) {
@@ -1490,8 +1490,15 @@ blink::WebMouseWheelEvent WebEventFactory::toWebWheelEvent(QWheelEvent *ev)
webEvent.SetType(webEventTypeForEvent(ev));
webEvent.SetModifiers(modifiersForEvent(ev));
webEvent.SetTimeStamp(base::TimeTicks::Now());
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
webEvent.SetPositionInWidget(ev->x(), ev->y());
webEvent.SetPositionInScreen(ev->globalX(), ev->globalY());
+#else
+ webEvent.SetPositionInWidget(static_cast<float>(ev->position().x()),
+ static_cast<float>(ev->position().y()));
+ webEvent.SetPositionInScreen(static_cast<float>(ev->globalPosition().x()),
+ static_cast<float>(ev->globalPosition().y()));
+#endif
webEvent.wheel_ticks_x = static_cast<float>(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep;
webEvent.wheel_ticks_y = static_cast<float>(ev->angleDelta().y()) / QWheelEvent::DefaultDeltasPerStep;
@@ -1520,8 +1527,15 @@ bool WebEventFactory::coalesceWebWheelEvent(blink::WebMouseWheelEvent &webEvent,
#endif
webEvent.SetTimeStamp(base::TimeTicks::Now());
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
webEvent.SetPositionInWidget(ev->x(), ev->y());
webEvent.SetPositionInScreen(ev->globalX(), ev->globalY());
+#else
+ webEvent.SetPositionInWidget(static_cast<float>(ev->position().x()),
+ static_cast<float>(ev->position().y()));
+ webEvent.SetPositionInScreen(static_cast<float>(ev->globalPosition().x()),
+ static_cast<float>(ev->globalPosition().y()));
+#endif
webEvent.wheel_ticks_x += static_cast<float>(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep;
webEvent.wheel_ticks_y += static_cast<float>(ev->angleDelta().y()) / QWheelEvent::DefaultDeltasPerStep;
diff --git a/src/process/support_win.cpp b/src/process/support_win.cpp
index 21481ce08..3d0ef37bf 100644
--- a/src/process/support_win.cpp
+++ b/src/process/support_win.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include <qlibrary.h>
+#include <qoperatingsystemversion.h>
#include <qsysinfo.h>
#include <qt_windows.h>
#include <Tlhelp32.h>
@@ -80,7 +81,7 @@ public:
ShcoreDLL()
: getProcessDpiAwareness(0), setProcessDpiAwareness(0)
{
- if (QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS8_1)
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8_1)
return;
library.setFileName(QStringLiteral("SHCore"));
if (!library.load())
diff --git a/src/src.pro b/src/src.pro
index 30562686a..de88878a6 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,32 +1,49 @@
+load(functions)
+
+include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri)
include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri)
-QT_FOR_CONFIG += webenginecore webenginecore-private
+include($$QTWEBENGINE_OUT_ROOT/src/webengine/qtwebengine-config.pri)
+include($$QTWEBENGINE_OUT_ROOT/src/webenginewidgets/qtwebenginewidgets-config.pri)
+
+QT_FOR_CONFIG += buildtools-private webenginecore webenginecore-private webengine-private \
+ webenginewidgets-private
TEMPLATE = subdirs
-process.depends = core
-webengine.depends = core
-webenginewidgets.depends = core webengine
-webengine_plugin.subdir = webengine/plugin
-webengine_plugin.target = sub-webengine-plugin
-webengine_plugin.depends = webengine
-core.depends = buildtools
+qtConfig(build-qtwebengine-core):qtConfig(webengine-core-support) {
+ core.depends = buildtools
+ process.depends = core
+ webengine.depends = core
+ webenginewidgets.depends = core webengine
+ webengine_plugin.subdir = webengine/plugin
+ webengine_plugin.target = sub-webengine-plugin
+ webengine_plugin.depends = webengine
-SUBDIRS += buildtools \
- core \
- process
+ SUBDIRS += buildtools core process
-qtConfig(webengine-spellchecker):!qtConfig(webengine-native-spellchecker):!cross_compile {
- SUBDIRS += qwebengine_convert_dict
- qwebengine_convert_dict.subdir = tools/qwebengine_convert_dict
- qwebengine_convert_dict.depends = core
-}
+ qtConfig(webengine-spellchecker):!qtConfig(webengine-native-spellchecker):!cross_compile {
+ SUBDIRS += qwebengine_convert_dict
+ qwebengine_convert_dict.subdir = tools/qwebengine_convert_dict
+ qwebengine_convert_dict.depends = core
+ }
+
+ qtConfig(webengine-qml) {
+ SUBDIRS += webengine
+ }
-qtConfig(webengine-qml) {
- SUBDIRS += webengine
+ qtConfig(webengine-widgets) {
+ SUBDIRS += plugins webenginewidgets
+ plugins.depends = webenginewidgets
+ }
}
-qtConfig(webengine-widgets) {
- SUBDIRS += plugins webenginewidgets
- plugins.depends = webenginewidgets
+!qtConfig(webengine-core-support): qtConfig(build-qtwebengine-core) {
+ !qtwebengine_makeCheckError():!isEmpty(skipBuildReason):!build_pass {
+ errorbuild.commands = @echo Modules will not be built. $${skipBuildReason}
+ errorbuild.CONFIG = phony
+ QMAKE_EXTRA_TARGETS += errorbuild
+ first.depends += errorbuild
+ QMAKE_EXTRA_TARGETS += first
+ }
}
diff --git a/src/webengine/api/qquickwebenginedialogrequests.cpp b/src/webengine/api/qquickwebenginedialogrequests.cpp
index d6bba9a98..da1aecaf6 100644
--- a/src/webengine/api/qquickwebenginedialogrequests.cpp
+++ b/src/webengine/api/qquickwebenginedialogrequests.cpp
@@ -44,6 +44,9 @@
#include "file_picker_controller.h"
#include "web_contents_adapter_client.h"
+#include <QCursor>
+#include <QQuickItem>
+
QT_BEGIN_NAMESPACE
using namespace QtWebEngineCore;
@@ -823,4 +826,111 @@ void QQuickWebEngineFormValidationMessageRequest::setAccepted(bool accepted)
m_accepted = accepted;
}
+///////////////////////////////////////////////////////////////////////////////
+
+/*!
+ \qmltype TooltipRequest
+ \instantiates QQuickWebEngineTooltipRequest
+ \inqmlmodule QtWebEngine
+ \since QtWebEngine 1.10
+
+ \brief A request for showing a tooltip to the user.
+*/
+
+QQuickWebEngineTooltipRequest::QQuickWebEngineTooltipRequest(
+ const QString &text, QObject *parent):
+ QObject(parent)
+ , m_text(text)
+ , m_type(text.isEmpty() ? RequestType::Hide : RequestType::Show)
+ , m_accepted(false)
+{
+ Q_ASSERT(parent);
+ if (QQuickItem *view = qobject_cast<QQuickItem *>(parent))
+ m_position = view->mapFromGlobal(view->cursor().pos()).toPoint();
+}
+
+QQuickWebEngineTooltipRequest::~QQuickWebEngineTooltipRequest()
+{
+
+}
+
+/*!
+ \qmlproperty int TooltipRequest::x
+ \readonly
+
+ The x coordinate of the top-left corner of the requested tooltip.
+*/
+
+int QQuickWebEngineTooltipRequest::x() const
+{
+ return m_position.x();
+}
+
+/*!
+ \qmlproperty int TooltipRequest::y
+ \readonly
+
+ The y coordinate of the top-left corner of the requested tooltip.
+*/
+
+int QQuickWebEngineTooltipRequest::y() const
+{
+ return m_position.y();
+}
+
+/*!
+ \qmlproperty bool TooltipRequest::text
+ \readonly
+
+ The text of the tooltip. It contains an empty string when the
+ tooltip should be hidden.
+*/
+
+
+QString QQuickWebEngineTooltipRequest::text() const
+{
+ return m_text;
+}
+
+/*!
+ \qmlproperty enumeration TooltipRequest::type
+ \readonly
+
+ The type of the tooltip request.
+
+ \value TooltipRequest.Show
+ The tooltip should be shown.
+ \value TooltipRequest.Hide
+ The tooltip should be hidden.
+*/
+
+QQuickWebEngineTooltipRequest::RequestType QQuickWebEngineTooltipRequest::type() const
+{
+ return m_type;
+}
+
+/*!
+ \qmlproperty bool TooltipRequest::accepted
+
+ Indicates whether the tooltip request has been accepted
+ by the signal handler.
+
+ If the property is \c false after any signal handlers
+ for WebEngineView::tooltipRequested have been executed,
+ a default tooltip will be shown.
+ To prevent this, set \c {request.accepted} to \c true.
+
+ The default is \c false.
+*/
+
+bool QQuickWebEngineTooltipRequest::isAccepted() const
+{
+ return m_accepted;
+}
+
+void QQuickWebEngineTooltipRequest::setAccepted(bool accepted)
+{
+ m_accepted = accepted;
+}
+
QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebenginedialogrequests_p.h b/src/webengine/api/qquickwebenginedialogrequests_p.h
index cdb10c26b..5e3f7c547 100644
--- a/src/webengine/api/qquickwebenginedialogrequests_p.h
+++ b/src/webengine/api/qquickwebenginedialogrequests_p.h
@@ -260,6 +260,39 @@ private:
friend class QQuickWebEngineViewPrivate;
};
+class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineTooltipRequest : public QObject {
+ Q_OBJECT
+public:
+ enum RequestType {
+ Show,
+ Hide,
+ };
+ Q_ENUM(RequestType)
+ Q_PROPERTY(int x READ x CONSTANT FINAL)
+ Q_PROPERTY(int y READ y CONSTANT FINAL)
+ Q_PROPERTY(QString text READ text CONSTANT FINAL)
+ Q_PROPERTY(RequestType type READ type CONSTANT FINAL)
+ Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted FINAL)
+
+ ~QQuickWebEngineTooltipRequest();
+ int x() const;
+ int y() const;
+ QString text() const;
+ RequestType type() const;
+ bool isAccepted() const;
+ void setAccepted(bool accepted);
+
+private:
+ QQuickWebEngineTooltipRequest(const QString &text = QString(),
+ QObject *parent = nullptr);
+ QPoint m_position;
+ QString m_text;
+ RequestType m_type;
+ bool m_accepted;
+ friend class QQuickWebEngineViewPrivate;
+ Q_DISABLE_COPY(QQuickWebEngineTooltipRequest)
+};
+
QT_END_NAMESPACE
#endif // QQUICKWEBENGINDIALOGREQUESTS_H
diff --git a/src/webengine/api/qquickwebenginedownloaditem.cpp b/src/webengine/api/qquickwebenginedownloaditem.cpp
index 7d51ed21d..3ccd27094 100644
--- a/src/webengine/api/qquickwebenginedownloaditem.cpp
+++ b/src/webengine/api/qquickwebenginedownloaditem.cpp
@@ -43,6 +43,7 @@
#include "profile_adapter.h"
#include "qquickwebengineprofile_p.h"
+#include <QDir>
#include "QFileInfo"
using QtWebEngineCore::ProfileAdapterClient;
@@ -98,7 +99,7 @@ static inline QQuickWebEngineDownloadItem::DownloadInterruptReason toDownloadInt
return static_cast<QQuickWebEngineDownloadItem::DownloadInterruptReason>(reason);
}
-QQuickWebEngineDownloadItemPrivate::QQuickWebEngineDownloadItemPrivate(QQuickWebEngineProfile *p)
+QQuickWebEngineDownloadItemPrivate::QQuickWebEngineDownloadItemPrivate(QQuickWebEngineProfile *p, const QUrl &url)
: profile(p)
, downloadId(-1)
, downloadState(QQuickWebEngineDownloadItem::DownloadCancelled)
@@ -110,6 +111,7 @@ QQuickWebEngineDownloadItemPrivate::QQuickWebEngineDownloadItemPrivate(QQuickWeb
, downloadFinished(false)
, downloadPaused(false)
, view(nullptr)
+ , downloadUrl(url)
{
}
@@ -388,6 +390,20 @@ qint64 QQuickWebEngineDownloadItem::receivedBytes() const
}
/*!
+ \qmlproperty url WebEngineDownloadItem::url
+ \readonly
+ \since QtWebEngine 1.10
+
+ Returns the download's origin URL.
+*/
+
+QUrl QQuickWebEngineDownloadItem::url() const
+{
+ Q_D(const QQuickWebEngineDownloadItem);
+ return d->downloadUrl;
+}
+
+/*!
\qmlproperty string WebEngineDownloadItem::mimeType
\since QtWebEngine 1.2
@@ -402,6 +418,7 @@ QString QQuickWebEngineDownloadItem::mimeType() const
/*!
\qmlproperty string WebEngineDownloadItem::path
+ \obsolete
Holds the full target path where data is being downloaded to.
@@ -418,7 +435,7 @@ QString QQuickWebEngineDownloadItem::mimeType() const
QString QQuickWebEngineDownloadItem::path() const
{
Q_D(const QQuickWebEngineDownloadItem);
- return d->downloadPath;
+ return QDir::cleanPath(QDir(d->downloadDirectory).filePath(d->downloadFileName));
}
void QQuickWebEngineDownloadItem::setPath(QString path)
@@ -428,7 +445,7 @@ void QQuickWebEngineDownloadItem::setPath(QString path)
qWarning("Setting the download path is not allowed after the download has been accepted.");
return;
}
- if (d->downloadPath != path) {
+ if (QDir(d->downloadDirectory).filePath(d->downloadFileName) != path) {
if (QFileInfo(path).fileName().isEmpty()) {
qWarning("The download path does not include file name.");
return;
@@ -439,12 +456,127 @@ void QQuickWebEngineDownloadItem::setPath(QString path)
return;
}
- d->downloadPath = path;
+ QString newDirectory;
+ QString newFileName;
+
+ if (QFileInfo(path).fileName() == path) {
+ newDirectory = QStringLiteral("");
+ newFileName = path;
+ } else {
+ newDirectory = QFileInfo(path).path();
+ newFileName = QFileInfo(path).fileName();
+ }
+
+ if (d->downloadDirectory != newDirectory) {
+ d->downloadDirectory = newDirectory;
+ Q_EMIT pathChanged();
+ Q_EMIT downloadDirectoryChanged();
+ }
+
+ if (d->downloadFileName != newFileName) {
+ d->downloadFileName = newFileName;
+ Q_EMIT pathChanged();
+ Q_EMIT downloadFileNameChanged();
+ }
+ }
+}
+
+/*!
+ \qmlproperty string WebEngineDownloadItem::downloadDirectory
+ \since QtWebEngine 1.10
+
+ Holds the full target path without file name where data is being downloaded to.
+
+ The download directory can only be set in the
+ \l{WebEngineProfile::downloadRequested}{downloadRequested} handler before
+ the download is accepted.
+
+ \sa WebEngineProfile::downloadRequested(), accept()
+*/
+
+QString QQuickWebEngineDownloadItem::downloadDirectory() const
+{
+ Q_D(const QQuickWebEngineDownloadItem);
+ return d->downloadDirectory;
+}
+
+void QQuickWebEngineDownloadItem::setDownloadDirectory(QString directory)
+{
+ Q_D(QQuickWebEngineDownloadItem);
+ if (d->downloadState != QQuickWebEngineDownloadItem::DownloadRequested) {
+ qWarning("Setting the download directory is not allowed after the download has been accepted.");
+ return;
+ }
+
+ QString changeDirectory = d->downloadDirectory;
+ if (!directory.isEmpty() && changeDirectory != directory) {
+ changeDirectory = directory;
+
+ if (d->downloadDirectory != changeDirectory) {
+ d->downloadDirectory = changeDirectory;
+ Q_EMIT pathChanged();
+ Q_EMIT downloadDirectoryChanged();
+ }
+
+ QString newFileName = QFileInfo(d->profile->d_ptr->profileAdapter()->updateDownloadPath(d->downloadId,
+ d->downloadDirectory,
+ d->suggestedFileName)).fileName();
+ if (d->downloadFileName != newFileName) {
+ d->downloadFileName = newFileName;
+ Q_EMIT pathChanged();
+ Q_EMIT downloadFileNameChanged();
+ }
+ }
+}
+
+/*!
+ \qmlproperty string WebEngineDownloadItem::downloadFileName
+ \since QtWebEngine 1.10
+
+ Holds the name of the file to which data is being downloaded.
+
+ The download file name can only be set in the
+ \l{WebEngineProfile::downloadRequested}{downloadRequested} handler before
+ the download is accepted.
+
+ \sa WebEngineProfile::downloadRequested(), accept()
+*/
+
+QString QQuickWebEngineDownloadItem::downloadFileName() const
+{
+ Q_D(const QQuickWebEngineDownloadItem);
+ return d->downloadFileName;
+}
+
+void QQuickWebEngineDownloadItem::setDownloadFileName(QString fileName)
+{
+ Q_D(QQuickWebEngineDownloadItem);
+ if (d->downloadState != QQuickWebEngineDownloadItem::DownloadRequested) {
+ qWarning("Setting the download file name is not allowed after the download has been accepted.");
+ return;
+ }
+
+ if (d->downloadFileName != fileName && !fileName.isEmpty()) {
+ d->downloadFileName = fileName;
Q_EMIT pathChanged();
+ Q_EMIT downloadFileNameChanged();
}
}
/*!
+ \qmlproperty string WebEngineDownloadItem::suggestedFileName
+ \since QtWebEngine 1.10
+
+ Returns the suggested file name.
+*/
+
+QString QQuickWebEngineDownloadItem::suggestedFileName() const
+{
+ Q_D(const QQuickWebEngineDownloadItem);
+ return d->suggestedFileName;
+}
+
+/*!
\qmlproperty enumeration WebEngineDownloadItem::savePageFormat
\since QtWebEngine 1.3
diff --git a/src/webengine/api/qquickwebenginedownloaditem_p.h b/src/webengine/api/qquickwebenginedownloaditem_p.h
index d19ca4828..cef99e534 100644
--- a/src/webengine/api/qquickwebenginedownloaditem_p.h
+++ b/src/webengine/api/qquickwebenginedownloaditem_p.h
@@ -55,6 +55,7 @@
#include <QObject>
#include <QScopedPointer>
#include <QString>
+#include <QUrl>
QT_BEGIN_NAMESPACE
@@ -136,6 +137,10 @@ public:
Q_PROPERTY(bool isPaused READ isPaused NOTIFY isPausedChanged REVISION 5 FINAL)
Q_PROPERTY(bool isSavePageDownload READ isSavePageDownload CONSTANT REVISION 6 FINAL)
Q_PROPERTY(QQuickWebEngineView *view READ view CONSTANT REVISION 7 FINAL)
+ Q_PROPERTY(QUrl url READ url CONSTANT REVISION 8 FINAL)
+ Q_PROPERTY(QString suggestedFileName READ suggestedFileName CONSTANT REVISION 8 FINAL)
+ Q_PROPERTY(QString downloadDirectory READ downloadDirectory WRITE setDownloadDirectory NOTIFY downloadDirectoryChanged REVISION 8 FINAL)
+ Q_PROPERTY(QString downloadFileName READ downloadFileName WRITE setDownloadFileName NOTIFY downloadFileNameChanged REVISION 8 FINAL)
Q_INVOKABLE void accept();
Q_INVOKABLE void cancel();
@@ -147,8 +152,8 @@ public:
qint64 totalBytes() const;
qint64 receivedBytes() const;
QString mimeType() const;
- QString path() const;
- void setPath(QString path);
+ QString Q_DECL_DEPRECATED path() const;
+ void Q_DECL_DEPRECATED setPath(QString path);
SavePageFormat savePageFormat() const;
void setSavePageFormat(SavePageFormat format);
DownloadType Q_DECL_DEPRECATED type() const;
@@ -158,6 +163,12 @@ public:
bool isPaused() const;
bool isSavePageDownload() const;
QQuickWebEngineView *view() const;
+ QUrl url() const;
+ QString suggestedFileName() const;
+ QString downloadDirectory() const;
+ void setDownloadDirectory(QString directory);
+ QString downloadFileName() const;
+ void setDownloadFileName(QString fileName);
Q_SIGNALS:
void stateChanged();
@@ -165,11 +176,13 @@ Q_SIGNALS:
void receivedBytesChanged();
void totalBytesChanged();
Q_REVISION(1) void mimeTypeChanged();
- void pathChanged();
+ void Q_DECL_DEPRECATED pathChanged();
Q_REVISION(3) void typeChanged();
Q_REVISION(4) void interruptReasonChanged();
Q_REVISION(5) void isFinishedChanged();
Q_REVISION(5) void isPausedChanged();
+ Q_REVISION(8) void downloadDirectoryChanged();
+ Q_REVISION(8) void downloadFileNameChanged();
private:
QQuickWebEngineDownloadItem(QQuickWebEngineDownloadItemPrivate*, QObject *parent = 0);
diff --git a/src/webengine/api/qquickwebenginedownloaditem_p_p.h b/src/webengine/api/qquickwebenginedownloaditem_p_p.h
index f444c04a5..51deee18b 100644
--- a/src/webengine/api/qquickwebenginedownloaditem_p_p.h
+++ b/src/webengine/api/qquickwebenginedownloaditem_p_p.h
@@ -67,7 +67,7 @@ class QQuickWebEngineDownloadItemPrivate {
friend class QQuickWebEngineProfilePrivate;
public:
Q_DECLARE_PUBLIC(QQuickWebEngineDownloadItem)
- QQuickWebEngineDownloadItemPrivate(QQuickWebEngineProfile *p);
+ QQuickWebEngineDownloadItemPrivate(QQuickWebEngineProfile *p, const QUrl &url);
~QQuickWebEngineDownloadItemPrivate();
quint32 downloadId;
@@ -82,6 +82,10 @@ public:
bool downloadFinished;
bool downloadPaused;
QQuickWebEngineView *view;
+ QUrl downloadUrl;
+ QString suggestedFileName;
+ QString downloadDirectory;
+ QString downloadFileName;
void update(const QtWebEngineCore::ProfileAdapterClient::DownloadItemInfo &info);
void updateState(QQuickWebEngineDownloadItem::DownloadState newState);
diff --git a/src/webengine/api/qquickwebenginenavigationrequest.cpp b/src/webengine/api/qquickwebenginenavigationrequest.cpp
index a6e253561..03c1d3d78 100644
--- a/src/webengine/api/qquickwebenginenavigationrequest.cpp
+++ b/src/webengine/api/qquickwebenginenavigationrequest.cpp
@@ -143,6 +143,8 @@ QQuickWebEngineView::NavigationRequestAction QQuickWebEngineNavigationRequest::a
Using navigation history to go to the previous or next page.
\value WebEngineNavigationRequest.ReloadNavigation
Reloading the page.
+ \value WebEngineNavigationRequest.RedirectNavigation
+ Page content or server triggered a redirection or page refresh.
\value WebEngineNavigationRequest.OtherNavigation
Using some other method to go to a page.
*/
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index 7630587fe..edad7ec44 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -48,6 +48,8 @@
#include "qwebenginecookiestore.h"
#include "qwebenginenotification.h"
+#include <QFileInfo>
+#include <QDir>
#include <QQmlEngine>
#include "profile_adapter.h"
@@ -240,12 +242,14 @@ void QQuickWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
Q_Q(QQuickWebEngineProfile);
Q_ASSERT(!m_ongoingDownloads.contains(info.id));
- QQuickWebEngineDownloadItemPrivate *itemPrivate = new QQuickWebEngineDownloadItemPrivate(q);
+ QQuickWebEngineDownloadItemPrivate *itemPrivate = new QQuickWebEngineDownloadItemPrivate(q, info.url);
itemPrivate->downloadId = info.id;
itemPrivate->downloadState = QQuickWebEngineDownloadItem::DownloadRequested;
itemPrivate->totalBytes = info.totalBytes;
itemPrivate->mimeType = info.mimeType;
- itemPrivate->downloadPath = info.path;
+ itemPrivate->downloadDirectory = QFileInfo(info.path).path();
+ itemPrivate->downloadFileName = QFileInfo(info.path).fileName();
+ itemPrivate->suggestedFileName = info.suggestedFileName;
itemPrivate->savePageFormat = static_cast<QQuickWebEngineDownloadItem::SavePageFormat>(
info.savePageFormat);
itemPrivate->type = static_cast<QQuickWebEngineDownloadItem::DownloadType>(info.downloadType);
@@ -263,7 +267,7 @@ void QQuickWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
Q_EMIT q->downloadRequested(download);
QQuickWebEngineDownloadItem::DownloadState state = download->state();
- info.path = download->path();
+ info.path = QDir(download->downloadDirectory()).filePath(download->downloadFileName());
info.savePageFormat = itemPrivate->savePageFormat;
info.accepted = state != QQuickWebEngineDownloadItem::DownloadCancelled
&& state != QQuickWebEngineDownloadItem::DownloadRequested;
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index fca69121a..8a1a3c516 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -43,6 +43,7 @@
#include "profile_adapter.h"
#include "certificate_error_controller.h"
#include "file_picker_controller.h"
+#include "find_text_helper.h"
#include "javascript_dialog_controller.h"
#include "touch_selection_menu_controller.h"
@@ -61,6 +62,7 @@
#include "qquickwebenginesettings_p.h"
#include "qquickwebenginescript_p.h"
#include "qquickwebenginetouchhandleprovider_p_p.h"
+#include "qwebenginefindtextresult.h"
#include "qwebenginequotarequest.h"
#include "qwebengineregisterprotocolhandlerrequest.h"
@@ -136,7 +138,7 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
memset(actions, 0, sizeof(actions));
QString platform = qApp->platformName().toLower();
- if (platform == QLatin1Literal("eglfs"))
+ if (platform == QLatin1String("eglfs"))
m_ui2Enabled = true;
const QByteArray dialogSet = qgetenv("QTWEBENGINE_DIALOG_SET");
@@ -164,7 +166,6 @@ QQuickWebEngineViewPrivate::~QQuickWebEngineViewPrivate()
{
Q_ASSERT(m_profileInitialized);
m_profile->d_ptr->removeWebContentsAdapterClient(this);
- adapter->stopFinding();
if (faviconProvider)
faviconProvider->detach(q_ptr);
// q_ptr->d_ptr might be null due to destroy()
@@ -273,8 +274,8 @@ void QQuickWebEngineViewPrivate::navigationRequested(int navigationType, const Q
Q_EMIT q->navigationRequested(&navigationRequest);
navigationRequestAction = navigationRequest.action();
- if ((navigationRequestAction == WebContentsAdapterClient::AcceptRequest) && adapter->isFindTextInProgress())
- adapter->stopFinding();
+ if ((navigationRequestAction == WebContentsAdapterClient::AcceptRequest) && adapter->findTextHelper()->isFindTextInProgress())
+ adapter->findTextHelper()->stopFinding();
}
void QQuickWebEngineViewPrivate::javascriptDialog(QSharedPointer<JavaScriptDialogController> dialog)
@@ -413,6 +414,11 @@ void QQuickWebEngineViewPrivate::didUpdateTargetURL(const QUrl &hoveredUrl)
Q_EMIT q->linkHovered(hoveredUrl);
}
+void QQuickWebEngineViewPrivate::selectionChanged()
+{
+ updateEditActions();
+}
+
void QQuickWebEngineViewPrivate::recentlyAudibleChanged(bool recentlyAudible)
{
Q_Q(QQuickWebEngineView);
@@ -694,6 +700,12 @@ void QQuickWebEngineViewPrivate::widgetChanged(RenderWidgetHostViewQtDelegate *n
bindViewAndWidget(q, static_cast<RenderWidgetHostViewQtDelegateQuick *>(newWidgetBase));
}
+void QQuickWebEngineViewPrivate::findTextFinished(const QWebEngineFindTextResult &result)
+{
+ Q_Q(QQuickWebEngineView);
+ Q_EMIT q->findTextFinished(result);
+}
+
WebEngineSettings *QQuickWebEngineViewPrivate::webEngineSettings() const
{
return m_settings->d_ptr.data();
@@ -705,6 +717,25 @@ const QObject *QQuickWebEngineViewPrivate::holdingQObject() const
return q;
}
+void QQuickWebEngineViewPrivate::lifecycleStateChanged(LifecycleState state)
+{
+ Q_Q(QQuickWebEngineView);
+ Q_EMIT q->lifecycleStateChanged(static_cast<QQuickWebEngineView::LifecycleState>(state));
+}
+
+void QQuickWebEngineViewPrivate::recommendedStateChanged(LifecycleState state)
+{
+ Q_Q(QQuickWebEngineView);
+ QTimer::singleShot(0, q, [q, state]() {
+ Q_EMIT q->recommendedStateChanged(static_cast<QQuickWebEngineView::LifecycleState>(state));
+ });
+}
+
+void QQuickWebEngineViewPrivate::visibleChanged(bool visible)
+{
+ Q_UNUSED(visible);
+}
+
#ifndef QT_NO_ACCESSIBILITY
QQuickWebEngineViewAccessible::QQuickWebEngineViewAccessible(QQuickWebEngineView *o)
: QAccessibleObject(o)
@@ -844,8 +875,8 @@ void QQuickWebEngineViewPrivate::initializationFinished()
for (QQuickWebEngineScript *script : qAsConst(m_userScripts))
script->d_func()->bind(profileAdapter()->userResourceController(), adapter.data());
- if (q->window() && q->isVisible())
- adapter->wasShown();
+ if (q->window())
+ adapter->setVisible(q->isVisible());
if (!m_isBeingAdopted)
return;
@@ -944,12 +975,14 @@ void QQuickWebEngineViewPrivate::updateAction(QQuickWebEngineView::WebAction act
break;
case QQuickWebEngineView::Cut:
case QQuickWebEngineView::Copy:
+ case QQuickWebEngineView::Unselect:
+ enabled = adapter->hasFocusedFrame() && !adapter->selectedText().isEmpty();
+ break;
case QQuickWebEngineView::Paste:
case QQuickWebEngineView::Undo:
case QQuickWebEngineView::Redo:
case QQuickWebEngineView::SelectAll:
case QQuickWebEngineView::PasteAndMatchStyle:
- case QQuickWebEngineView::Unselect:
enabled = adapter->hasFocusedFrame();
break;
default:
@@ -1025,13 +1058,13 @@ void QQuickWebEngineView::loadHtml(const QString &html, const QUrl &baseUrl)
void QQuickWebEngineView::goBack()
{
Q_D(QQuickWebEngineView);
- d->adapter->navigateToOffset(-1);
+ d->adapter->navigateBack();
}
void QQuickWebEngineView::goForward()
{
Q_D(QQuickWebEngineView);
- d->adapter->navigateToOffset(1);
+ d->adapter->navigateForward();
}
void QQuickWebEngineView::reload()
@@ -1157,14 +1190,6 @@ void QQuickWebEngineViewPrivate::didRunJavaScript(quint64 requestId, const QVari
callback.call(args);
}
-void QQuickWebEngineViewPrivate::didFindText(quint64 requestId, int matchCount)
-{
- QJSValue callback = m_callbacks.take(requestId);
- QJSValueList args;
- args.append(QJSValue(matchCount));
- callback.call(args);
-}
-
void QQuickWebEngineViewPrivate::didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result)
{
Q_Q(QQuickWebEngineView);
@@ -1235,7 +1260,13 @@ bool QQuickWebEngineViewPrivate::isEnabled() const
void QQuickWebEngineViewPrivate::setToolTip(const QString &toolTipText)
{
- ui()->showToolTip(toolTipText);
+ Q_Q(QQuickWebEngineView);
+ QQuickWebEngineTooltipRequest *request = new QQuickWebEngineTooltipRequest(toolTipText, q);
+ // mark the object for gc by creating temporary jsvalue
+ qmlEngine(q)->newQObject(request);
+ Q_EMIT q->tooltipRequested(request);
+ if (!request->isAccepted())
+ ui()->showToolTip(toolTipText);
}
QtWebEngineCore::TouchHandleDrawableClient *QQuickWebEngineViewPrivate::createTouchHandle(const QMap<int, QImage> &images)
@@ -1430,18 +1461,8 @@ void QQuickWebEngineView::findText(const QString &subString, FindFlags options,
Q_D(QQuickWebEngineView);
if (!d->adapter->isInitialized())
return;
- if (subString.isEmpty()) {
- d->adapter->stopFinding();
- if (!callback.isUndefined()) {
- QJSValueList args;
- args.append(QJSValue(0));
- const_cast<QJSValue&>(callback).call(args);
- }
- } else {
- quint64 requestId = d->adapter->findText(subString, options & FindCaseSensitively, options & FindBackward);
- if (!callback.isUndefined())
- d->m_callbacks.insert(requestId, callback);
- }
+
+ d->adapter->findTextHelper()->startFinding(subString, options & FindCaseSensitively, options & FindBackward, callback);
}
QQuickWebEngineHistory *QQuickWebEngineView::navigationHistory() const
@@ -1631,10 +1652,8 @@ void QQuickWebEngineView::itemChange(ItemChange change, const ItemChangeData &va
Q_D(QQuickWebEngineView);
if (d && d->profileInitialized() && d->adapter->isInitialized()
&& (change == ItemSceneChange || change == ItemVisibleHasChanged)) {
- if (window() && isVisible())
- d->adapter->wasShown();
- else
- d->adapter->wasHidden();
+ if (window())
+ d->adapter->setVisible(isVisible());
}
QQuickItem::itemChange(change, value);
}
@@ -1684,10 +1703,10 @@ void QQuickWebEngineView::triggerWebAction(WebAction action)
Q_D(QQuickWebEngineView);
switch (action) {
case Back:
- d->adapter->navigateToOffset(-1);
+ d->adapter->navigateBack();
break;
case Forward:
- d->adapter->navigateToOffset(1);
+ d->adapter->navigateForward();
break;
case Stop:
d->adapter->stop();
@@ -2146,6 +2165,24 @@ void QQuickWebEngineView::lazyInitialize()
d->ensureContentsAdapter();
}
+QQuickWebEngineView::LifecycleState QQuickWebEngineView::lifecycleState() const
+{
+ Q_D(const QQuickWebEngineView);
+ return static_cast<LifecycleState>(d->adapter->lifecycleState());
+}
+
+void QQuickWebEngineView::setLifecycleState(LifecycleState state)
+{
+ Q_D(QQuickWebEngineView);
+ d->adapter->setLifecycleState(static_cast<WebContentsAdapterClient::LifecycleState>(state));
+}
+
+QQuickWebEngineView::LifecycleState QQuickWebEngineView::recommendedState() const
+{
+ Q_D(const QQuickWebEngineView);
+ return static_cast<LifecycleState>(d->adapter->recommendedState());
+}
+
QQuickWebEngineFullScreenRequest::QQuickWebEngineFullScreenRequest()
: m_viewPrivate(0)
, m_toggleOn(false)
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index c851dcb8d..4a88e3c28 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -76,8 +76,10 @@ class QQuickWebEngineNavigationRequest;
class QQuickWebEngineNewViewRequest;
class QQuickWebEngineProfile;
class QQuickWebEngineSettings;
+class QQuickWebEngineTooltipRequest;
class QQuickWebEngineFormValidationMessageRequest;
class QQuickWebEngineViewPrivate;
+class QWebEngineFindTextResult;
class QWebEngineQuotaRequest;
class QWebEngineRegisterProtocolHandlerRequest;
@@ -104,10 +106,11 @@ private:
const bool m_toggleOn;
};
-#define LATEST_WEBENGINEVIEW_REVISION 9
+#define LATEST_WEBENGINEVIEW_REVISION 10
class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
Q_OBJECT
+ Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged FINAL)
Q_PROPERTY(QUrl icon READ icon NOTIFY iconChanged FINAL)
Q_PROPERTY(bool loading READ isLoading NOTIFY loadingChanged FINAL)
@@ -136,6 +139,9 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
Q_PROPERTY(QQuickWebEngineTestSupport *testSupport READ testSupport WRITE setTestSupport NOTIFY testSupportChanged FINAL)
#endif
+ Q_PROPERTY(LifecycleState lifecycleState READ lifecycleState WRITE setLifecycleState NOTIFY lifecycleStateChanged REVISION 11 FINAL)
+ Q_PROPERTY(LifecycleState recommendedState READ recommendedState NOTIFY recommendedStateChanged REVISION 11 FINAL)
+
public:
QQuickWebEngineView(QQuickItem *parent = 0);
~QQuickWebEngineView();
@@ -172,7 +178,8 @@ public:
FormSubmittedNavigation,
BackForwardNavigation,
ReloadNavigation,
- OtherNavigation
+ OtherNavigation,
+ RedirectNavigation,
};
Q_ENUM(NavigationType)
@@ -459,6 +466,14 @@ public:
};
Q_ENUM(PrintedPageOrientation)
+ // must match WebContentsAdapterClient::LifecycleState
+ enum class LifecycleState {
+ Active,
+ Frozen,
+ Discarded,
+ };
+ Q_ENUM(LifecycleState)
+
// QmlParserStatus
void componentComplete() override;
@@ -490,6 +505,11 @@ public:
void setDevToolsView(QQuickWebEngineView *);
QQuickWebEngineView *devToolsView() const;
+ LifecycleState lifecycleState() const;
+ void setLifecycleState(LifecycleState state);
+
+ LifecycleState recommendedState() const;
+
public Q_SLOTS:
void runJavaScript(const QString&, const QJSValue & = QJSValue());
Q_REVISION(3) void runJavaScript(const QString&, quint32 worldId, const QJSValue & = QJSValue());
@@ -552,6 +572,10 @@ Q_SIGNALS:
Q_REVISION(7) void registerProtocolHandlerRequested(const QWebEngineRegisterProtocolHandlerRequest &request);
Q_REVISION(8) void printRequested();
Q_REVISION(9) void selectClientCertificate(QQuickWebEngineClientCertificateSelection *clientCertSelection);
+ Q_REVISION(10) void tooltipRequested(QQuickWebEngineTooltipRequest *request);
+ Q_REVISION(11) void lifecycleStateChanged(LifecycleState state);
+ Q_REVISION(11) void recommendedStateChanged(LifecycleState state);
+ Q_REVISION(11) void findTextFinished(const QWebEngineFindTextResult &result);
#if QT_CONFIG(webengine_testsupport)
void testSupportChanged();
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index 10fe5c2fd..df6843ac3 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -80,6 +80,7 @@ class QQuickWebEngineSettings;
class QQuickWebEngineFaviconProvider;
class QQuickWebEngineProfilePrivate;
class QQuickWebEngineTouchHandleProvider;
+class QWebEngineFindTextResult;
QQuickWebEngineView::WebAction editorActionForKeyEvent(QKeyEvent* event);
@@ -101,12 +102,15 @@ public:
QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override;
QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegateForPopup(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override;
void initializationFinished() override;
+ void lifecycleStateChanged(LifecycleState state) override;
+ void recommendedStateChanged(LifecycleState state) override;
+ void visibleChanged(bool visible) override;
void titleChanged(const QString&) override;
void urlChanged(const QUrl&) override;
void iconChanged(const QUrl&) override;
void loadProgressChanged(int progress) override;
void didUpdateTargetURL(const QUrl&) override;
- void selectionChanged() override { }
+ void selectionChanged() override;
void recentlyAudibleChanged(bool recentlyAudible) override;
QRectF viewportRect() const override;
QColor backgroundColor() const override;
@@ -130,7 +134,6 @@ public:
void didRunJavaScript(quint64, const QVariant&) override;
void didFetchDocumentMarkup(quint64, const QString&) override { }
void didFetchDocumentInnerText(quint64, const QString&) override { }
- void didFindText(quint64, int) override;
void didPrintPage(quint64 requestId, QSharedPointer<QByteArray>) override;
void didPrintPageToPdf(const QString &filePath, bool success) override;
bool passOnFocus(bool reverse) override;
@@ -167,6 +170,7 @@ public:
QtWebEngineCore::WebContentsAdapter *webContentsAdapter() override;
void printRequested() override;
void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegate *newWidgetBase) override;
+ void findTextFinished(const QWebEngineFindTextResult &result) override;
void updateAction(QQuickWebEngineView::WebAction) const;
void adoptWebContents(QtWebEngineCore::WebContentsAdapter *webContents);
diff --git a/src/webengine/configure.json b/src/webengine/configure.json
index ca0e5c2fd..ebe1ddb2b 100644
--- a/src/webengine/configure.json
+++ b/src/webengine/configure.json
@@ -1,10 +1,20 @@
{
"module": "webengine",
+ "condition": "module.webenginecore && features.webengine-qml",
"depends": [
"webenginecore-private"
],
- "condition": "module.webenginecore",
+ "commandline": {
+ "options": {
+ "webengine-qml": "boolean"
+ }
+ },
"features": {
+ "webengine-qml": {
+ "label": "Support Qt WebEngine Qml",
+ "purpose": "Provides WebEngine Qml support.",
+ "output": [ "privateFeature" ]
+ },
"webengine-ui-delegates": {
"label": "UI Delegates",
"section": "WebEngine",
@@ -19,8 +29,8 @@
"summary": [
{
"section": "Qt WebEngineQml",
- "condition": "features.webengine-qml",
"entries": [
+ "webengine-qml",
"webengine-ui-delegates",
"webengine-testsupport"
]
diff --git a/src/webengine/doc/src/webengineview_lgpl.qdoc b/src/webengine/doc/src/webengineview_lgpl.qdoc
index 7efe447ac..9abc8f37b 100644
--- a/src/webengine/doc/src/webengineview_lgpl.qdoc
+++ b/src/webengine/doc/src/webengineview_lgpl.qdoc
@@ -415,26 +415,33 @@
\qmlmethod void WebEngineView::findText(string subString)
\since QtWebEngine 1.1
Finds the specified string, \a subString, in the page.
+ The findTextFinished() signal is emitted when a string search is completed.
To clear the search highlight, just pass an empty string.
+
+ \sa findTextFinished()
*/
/*!
\qmlmethod void WebEngineView::findText(string subString, FindFlags options)
\since QtWebEngine 1.1
Finds the specified string, \a subString, in the page, using the given \a options.
+ The findTextFinished() signal is emitted when a string search is completed.
To clear the search highlight, just pass an empty string.
\code
findText("Qt", WebEngineView.FindBackward | WebEngineView.FindCaseSensitively);
\endcode
+
+ \sa findTextFinished()
*/
/*!
\qmlmethod void WebEngineView::findText(string subString, FindFlags options, variant resultCallback)
\since QtWebEngine 1.1
Finds the specified string, \a subString, in the page, using the given \a options.
+ The findTextFinished() signal is emitted when a string search is completed.
To clear the search highlight, just pass an empty string.
@@ -447,6 +454,8 @@
console.log("'Qt' tokens found:", matchCount);
});
\endcode
+
+ \sa findTextFinished()
*/
/*!
@@ -1506,3 +1515,102 @@
\sa WebEngineClientCertificateSelection
*/
+
+/*!
+ \qmlsignal WebEngineView::tooltipRequested(TooltipRequest request)
+ \since QtWebEngine 1.10
+
+ This signal is emitted when the web page wants to show a tooltip at
+ a specified position.
+
+ \note Signal handlers need to call \c{request.accepted = true} to prevent a default tooltip from showing up.
+
+ \sa TooltipRequest
+*/
+
+/*!
+ \qmlproperty enumeration WebEngineView::LifecycleState
+ \since QtWebEngine 1.11
+
+ This enum describes the lifecycle state of the page:
+
+ \value WebEngineView.LifecycleState.Active
+ Normal state.
+ \value WebEngineView.LifecycleState.Frozen
+ Low CPU usage state where most HTML task sources are suspended.
+ \value WebEngineView.LifecycleState.Discarded
+ Very low resource usage state where the entire browsing context is discarded.
+
+ \sa lifecycleState
+*/
+
+/*!
+ \qmlproperty LifecycleState WebEngineView::lifecycleState
+ \since QtWebEngine 1.11
+
+ \brief The current lifecycle state of the page.
+
+ The following restrictions are enforced by the setter:
+
+ \list
+ \li A visible page must remain in the \c{Active} state.
+ \li If the page is being inspected by a \l{devToolsView} then both pages must
+ remain in the \c{Active} states.
+ \li A page in the \c{Discarded} state can only transition to the \c{Active}
+ state. This will cause a reload of the page.
+ \endlist
+
+ These are the only hard limits on the lifecycle state, but see also
+ \l{recommendedState} for the recommended soft limits.
+
+ \sa recommendedState, {WebEngine Lifecycle Example}
+*/
+
+/*!
+ \qmlproperty LifecycleState WebEngineView::recommendedState
+ \since QtWebEngine 1.11
+
+ \brief The recommended limit for the lifecycle state of the page.
+
+ Setting the lifecycle state to a lower resource usage state than the
+ recommended state may cause side-effects such as stopping background audio
+ playback or loss of HTML form input. Setting the lifecycle state to a higher
+ resource state is however completely safe.
+
+ \sa lifecycleState, {WebEngine Lifecycle Example}
+*/
+
+/*!
+ \qmltype FindTextResult
+ \instantiates QWebEngineFindTextResult
+ \inqmlmodule QtWebEngine
+ \since QtWebEngine 1.11
+
+ \brief A utility type for encapsulating the result of a string search on a page.
+
+ \sa WebEngineView::findTextFinished()
+*/
+
+/*!
+ \qmlproperty int FindTextResult::numberOfMatches
+ \readonly
+
+ \brief The number of matches found.
+*/
+
+/*!
+ \qmlproperty int FindTextResult::activeMatchOrdinal
+ \readonly
+
+ \brief The index of the currently highlighted match.
+*/
+
+/*!
+ \qmlsignal WebEngineView::findTextFinished(FindTextResult result)
+ \since QtWebEngine 1.11
+
+ This signal is emitted when a string search on a page is completed. \a result is
+ the result of the string search.
+
+ \sa findText(), FindTextResult
+*/
diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp
index a332288d4..5fb48d867 100644
--- a/src/webengine/plugin/plugin.cpp
+++ b/src/webengine/plugin/plugin.cpp
@@ -55,6 +55,7 @@
#include <QtWebEngine/private/qquickwebenginetouchhandleprovider_p_p.h>
#include <QtWebEngine/private/qquickwebengineview_p.h>
#include <QtWebEngine/private/qquickwebengineaction_p.h>
+#include <QtWebEngineCore/qwebenginefindtextresult.h>
#include <QtWebEngineCore/qwebenginenotification.h>
#include <QtWebEngineCore/qwebenginequotarequest.h>
#include <QtWebEngineCore/qwebengineregisterprotocolhandlerrequest.h>
@@ -95,6 +96,8 @@ public:
qmlRegisterType<QQuickWebEngineView, 7>(uri, 1, 7, "WebEngineView");
qmlRegisterType<QQuickWebEngineView, 8>(uri, 1, 8, "WebEngineView");
qmlRegisterType<QQuickWebEngineView, 9>(uri, 1, 9, "WebEngineView");
+ qmlRegisterType<QQuickWebEngineView, 10>(uri, 1, 10, "WebEngineView");
+ qmlRegisterType<QQuickWebEngineView, 11>(uri, 1, 11, "WebEngineView");
qmlRegisterType<QQuickWebEngineProfile>(uri, 1, 1, "WebEngineProfile");
qmlRegisterType<QQuickWebEngineProfile, 1>(uri, 1, 2, "WebEngineProfile");
qmlRegisterType<QQuickWebEngineProfile, 2>(uri, 1, 3, "WebEngineProfile");
@@ -104,21 +107,23 @@ public:
qmlRegisterType<QQuickWebEngineScript>(uri, 1, 1, "WebEngineScript");
qmlRegisterUncreatableType<QQuickWebEngineCertificateError>(uri, 1, 1, "WebEngineCertificateError", msgUncreatableType("WebEngineCertificateError"));
qmlRegisterUncreatableType<QQuickWebEngineDownloadItem>(uri, 1, 1, "WebEngineDownloadItem",
- tr("Cannot create a separate instance of WebEngineDownloadItem"));
+ msgUncreatableType("WebEngineDownloadItem"));
qmlRegisterUncreatableType<QQuickWebEngineDownloadItem, 1>(uri, 1, 2, "WebEngineDownloadItem",
- tr("Cannot create a separate instance of WebEngineDownloadItem"));
+ msgUncreatableType("WebEngineDownloadItem"));
qmlRegisterUncreatableType<QQuickWebEngineDownloadItem, 2>(uri, 1, 3, "WebEngineDownloadItem",
- tr("Cannot create a separate instance of WebEngineDownloadItem"));
+ msgUncreatableType("WebEngineDownloadItem"));
qmlRegisterUncreatableType<QQuickWebEngineDownloadItem, 3>(uri, 1, 4, "WebEngineDownloadItem",
- tr("Cannot create a separate instance of WebEngineDownloadItem"));
+ msgUncreatableType("WebEngineDownloadItem"));
qmlRegisterUncreatableType<QQuickWebEngineDownloadItem, 4>(uri, 1, 5, "WebEngineDownloadItem",
- tr("Cannot create a separate instance of WebEngineDownloadItem"));
+ msgUncreatableType("WebEngineDownloadItem"));
qmlRegisterUncreatableType<QQuickWebEngineDownloadItem, 5>(uri, 1, 6, "WebEngineDownloadItem",
- tr("Cannot create a separate instance of WebEngineDownloadItem"));
+ msgUncreatableType("WebEngineDownloadItem"));
qmlRegisterUncreatableType<QQuickWebEngineDownloadItem, 6>(uri, 1, 7, "WebEngineDownloadItem",
- tr("Cannot create a separate instance of WebEngineDownloadItem"));
+ msgUncreatableType("WebEngineDownloadItem"));
qmlRegisterUncreatableType<QQuickWebEngineDownloadItem, 7>(uri, 1, 8, "WebEngineDownloadItem",
- tr("Cannot create a separate instance of WebEngineDownloadItem"));
+ msgUncreatableType("WebEngineDownloadItem"));
+ qmlRegisterUncreatableType<QQuickWebEngineDownloadItem, 8>(uri, 1, 10, "WebEngineDownloadItem",
+ msgUncreatableType("WebEngineDownloadItem"));
qmlRegisterUncreatableType<QQuickWebEngineNewViewRequest>(uri, 1, 1, "WebEngineNewViewRequest", msgUncreatableType("WebEngineNewViewRequest"));
qmlRegisterUncreatableType<QQuickWebEngineNewViewRequest, 1>(uri, 1, 5, "WebEngineNewViewRequest", tr("Cannot create separate instance of WebEngineNewViewRequest"));
qmlRegisterUncreatableType<QQuickWebEngineSettings>(uri, 1, 1, "WebEngineSettings", msgUncreatableType("WebEngineSettings"));
@@ -132,11 +137,11 @@ public:
qmlRegisterUncreatableType<QQuickWebEngineSettings, 8>(uri, 1, 9, "WebEngineSettings", msgUncreatableType("WebEngineSettings"));
qmlRegisterSingletonType<QQuickWebEngineSingleton>(uri, 1, 1, "WebEngine", webEngineSingletonProvider);
qmlRegisterUncreatableType<QQuickWebEngineHistory>(uri, 1, 1, "NavigationHistory",
- tr("Cannot create a separate instance of NavigationHistory"));
+ msgUncreatableType("NavigationHistory"));
qmlRegisterUncreatableType<QQuickWebEngineHistoryListModel>(uri, 1, 1, "NavigationHistoryListModel",
- tr("Cannot create a separate instance of NavigationHistory"));
+ msgUncreatableType("NavigationHistory"));
qmlRegisterUncreatableType<QQuickWebEngineFullScreenRequest>(uri, 1, 1, "FullScreenRequest",
- tr("Cannot create a separate instance of FullScreenRequest"));
+ msgUncreatableType("FullScreenRequest"));
qmlRegisterUncreatableType<QQuickWebEngineContextMenuRequest>(uri, 1, 4, "ContextMenuRequest",
msgUncreatableType("ContextMenuRequest"));
@@ -166,6 +171,10 @@ public:
msgUncreatableType("WebEngineClientCertificateOption"));
#endif
qmlRegisterUncreatableType<QWebEngineNotification>(uri, 1, 9, "WebEngineNotification", msgUncreatableType("WebEngineNotification"));
+ qmlRegisterUncreatableType<QQuickWebEngineTooltipRequest>(uri, 1, 10, "TooltipRequest",
+ msgUncreatableType("TooltipRequest"));
+ qRegisterMetaType<QWebEngineFindTextResult>();
+ qmlRegisterUncreatableType<QWebEngineFindTextResult>(uri, 1, 11, "FindTextResult", msgUncreatableType("FindTextResult"));
}
private:
diff --git a/src/webengine/plugin/plugin.pro b/src/webengine/plugin/plugin.pro
index 0c1310de3..3b30bece2 100644
--- a/src/webengine/plugin/plugin.pro
+++ b/src/webengine/plugin/plugin.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = qtwebengineplugin
TARGETPATH = QtWebEngine
-IMPORT_VERSION = 1.9
+IMPORT_VERSION = 1.10
QT += qml quick
QT_PRIVATE += core-private webenginecore-private webengine-private
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
index 55ec19fc9..ac32671aa 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
@@ -174,12 +174,6 @@ QSGLayer *RenderWidgetHostViewQtDelegateQuick::createLayer()
return renderContext->sceneGraphContext()->createLayer(renderContext);
}
-QSGInternalImageNode *RenderWidgetHostViewQtDelegateQuick::createInternalImageNode()
-{
- QSGRenderContext *renderContext = QQuickWindowPrivate::get(QQuickItem::window())->context;
- return renderContext->sceneGraphContext()->createInternalImageNode();
-}
-
QSGImageNode *RenderWidgetHostViewQtDelegateQuick::createImageNode()
{
return QQuickItem::window()->createImageNode();
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.h b/src/webengine/render_widget_host_view_qt_delegate_quick.h
index 00158b3ac..b55b2d658 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h
@@ -71,7 +71,6 @@ public:
QWindow* window() const override;
QSGTexture *createTextureFromImage(const QImage &) override;
QSGLayer *createLayer() override;
- QSGInternalImageNode *createInternalImageNode() override;
QSGImageNode *createImageNode() override;
QSGRectangleNode *createRectangleNode() override;
void update() override;
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
index 3648df3c1..d3ebdbf27 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
@@ -131,11 +131,6 @@ QSGLayer *RenderWidgetHostViewQtDelegateQuickWindow::createLayer()
return m_realDelegate->createLayer();
}
-QSGInternalImageNode *RenderWidgetHostViewQtDelegateQuickWindow::createInternalImageNode()
-{
- return m_realDelegate->createInternalImageNode();
-}
-
QSGImageNode *RenderWidgetHostViewQtDelegateQuickWindow::createImageNode()
{
return m_realDelegate->createImageNode();
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
index ab583bd63..bebbfa439 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
@@ -68,7 +68,6 @@ public:
QWindow* window() const override;
QSGTexture *createTextureFromImage(const QImage &) override;
QSGLayer *createLayer() override;
- QSGInternalImageNode *createInternalImageNode() override;
QSGImageNode *createImageNode() override;
QSGRectangleNode *createRectangleNode() override;
void update() override;
diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp
index 2f371efd5..19274bedf 100644
--- a/src/webengine/ui_delegates_manager.cpp
+++ b/src/webengine/ui_delegates_manager.cpp
@@ -539,14 +539,14 @@ void UIDelegatesManager::showMenu(QObject *menu)
void UIDelegatesManager::showToolTip(const QString &text)
{
- if (!ensureComponentLoaded(ToolTip))
- return;
-
if (text.isEmpty()) {
m_toolTip.reset();
return;
}
+ if (!ensureComponentLoaded(ToolTip))
+ return;
+
if (!m_toolTip.isNull())
return;
diff --git a/src/webenginewidgets/api/qwebenginecertificateerror.cpp b/src/webenginewidgets/api/qwebenginecertificateerror.cpp
index f04b73615..a61d98f94 100644
--- a/src/webenginewidgets/api/qwebenginecertificateerror.cpp
+++ b/src/webenginewidgets/api/qwebenginecertificateerror.cpp
@@ -39,6 +39,8 @@
#include "qwebenginecertificateerror.h"
+#include "certificate_error_controller.h"
+
QT_BEGIN_NAMESPACE
/*!
@@ -51,14 +53,38 @@ QT_BEGIN_NAMESPACE
QWebEnginePage::certificateError().
*/
-class QWebEngineCertificateErrorPrivate {
+class QWebEngineCertificateErrorPrivate : public QSharedData {
public:
QWebEngineCertificateErrorPrivate(int error, QUrl url, bool overridable, QString errorDescription);
+ ~QWebEngineCertificateErrorPrivate() {
+ if (deferred && !answered)
+ rejectCertificate();
+ }
+
+ void resolveError(bool accept) {
+ if (answered)
+ return;
+ answered = true;
+ if (overridable) {
+ if (auto ctl = controller.lock())
+ ctl->accept(accept);
+ }
+ }
+
+ void ignoreCertificateError() { resolveError(true); }
+ void rejectCertificate() { resolveError(false); }
+
QWebEngineCertificateError::Error error;
QUrl url;
bool overridable;
QString errorDescription;
+ QList<QSslCertificate> chain;
+
+ bool answered = false, deferred = false;
+ QWeakPointer<CertificateErrorController> controller;
+
+ Q_DISABLE_COPY(QWebEngineCertificateErrorPrivate)
};
QWebEngineCertificateErrorPrivate::QWebEngineCertificateErrorPrivate(int error, QUrl url, bool overridable, QString errorDescription)
@@ -68,17 +94,31 @@ QWebEngineCertificateErrorPrivate::QWebEngineCertificateErrorPrivate(int error,
, errorDescription(errorDescription)
{ }
-
/*! \internal
*/
QWebEngineCertificateError::QWebEngineCertificateError(int error, QUrl url, bool overridable, QString errorDescription)
- : d_ptr(new QWebEngineCertificateErrorPrivate(error, url, overridable, errorDescription))
+ : d(new QWebEngineCertificateErrorPrivate(error, url, overridable, errorDescription))
{ }
/*! \internal
*/
+QWebEngineCertificateError::QWebEngineCertificateError(const QSharedPointer<CertificateErrorController> &controller)
+ : d(new QWebEngineCertificateErrorPrivate(controller->error(), controller->url(),
+ controller->overridable(), controller->errorString()))
+{
+ d->controller = controller;
+ d->chain = controller->chain();
+}
+
+QWebEngineCertificateError::QWebEngineCertificateError(const QWebEngineCertificateError &other) = default;
+
+QWebEngineCertificateError& QWebEngineCertificateError::operator=(const QWebEngineCertificateError &other) = default;
+
+/*! \internal
+*/
QWebEngineCertificateError::~QWebEngineCertificateError()
{
+
}
/*!
@@ -116,7 +156,6 @@ QWebEngineCertificateError::~QWebEngineCertificateError()
*/
bool QWebEngineCertificateError::isOverridable() const
{
- const Q_D(QWebEngineCertificateError);
return d->overridable;
}
@@ -127,7 +166,6 @@ bool QWebEngineCertificateError::isOverridable() const
*/
QUrl QWebEngineCertificateError::url() const
{
- const Q_D(QWebEngineCertificateError);
return d->url;
}
@@ -138,7 +176,6 @@ QUrl QWebEngineCertificateError::url() const
*/
QWebEngineCertificateError::Error QWebEngineCertificateError::error() const
{
- const Q_D(QWebEngineCertificateError);
return d->error;
}
@@ -149,8 +186,66 @@ QWebEngineCertificateError::Error QWebEngineCertificateError::error() const
*/
QString QWebEngineCertificateError::errorDescription() const
{
- const Q_D(QWebEngineCertificateError);
return d->errorDescription;
}
+/*!
+ Marks the certificate error for delayed handling.
+
+ This function should be called when there is a need to postpone the decision whether to ignore a
+ certificate error, for example, while waiting for user input. When called, the function pauses the
+ URL request until ignoreCertificateError() or rejectCertificate() is called.
+
+ \note It is only possible to defer overridable certificate errors.
+
+ \sa isOverridable(), deferred()
+*/
+void QWebEngineCertificateError::defer()
+{
+ if (isOverridable())
+ d->deferred = true;
+}
+
+/*!
+ Returns whether the decision for error handling was delayed and the URL load was halted.
+*/
+bool QWebEngineCertificateError::deferred() const
+{
+ return d->deferred;
+}
+
+/*!
+ Ignores the certificate error and continues the loading of the requested URL.
+*/
+void QWebEngineCertificateError::ignoreCertificateError()
+{
+ d->ignoreCertificateError();
+}
+
+/*!
+ Rejects the certificate and aborts the loading of the requested URL.
+*/
+void QWebEngineCertificateError::rejectCertificate()
+{
+ d->rejectCertificate();
+}
+
+/*!
+ Returns \c true if the error was explicitly rejected or accepted.
+*/
+bool QWebEngineCertificateError::answered() const
+{
+ return d->answered;
+}
+
+/*!
+ Returns the peer's chain of digital certificates
+
+ Chain starts with the peer's immediate certificate and ending with the CA's certificate.
+*/
+QList<QSslCertificate> QWebEngineCertificateError::chain() const
+{
+ return d->chain;
+}
+
QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebenginecertificateerror.h b/src/webenginewidgets/api/qwebenginecertificateerror.h
index 82ac281be..b2dd65a9f 100644
--- a/src/webenginewidgets/api/qwebenginecertificateerror.h
+++ b/src/webenginewidgets/api/qwebenginecertificateerror.h
@@ -42,11 +42,13 @@
#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h>
-#include <QtCore/qscopedpointer.h>
+#include <QtCore/qsharedpointer.h>
#include <QtCore/qurl.h>
+#include <QtNetwork/QSslCertificate>
QT_BEGIN_NAMESPACE
+class CertificateErrorController;
class QWebEngineCertificateErrorPrivate;
class QWEBENGINEWIDGETS_EXPORT QWebEngineCertificateError {
@@ -78,10 +80,22 @@ public:
bool isOverridable() const;
QString errorDescription() const;
+ QWebEngineCertificateError(const QWebEngineCertificateError &other);
+ QWebEngineCertificateError& operator=(const QWebEngineCertificateError &other);
+
+ void defer();
+ bool deferred() const;
+
+ void rejectCertificate();
+ void ignoreCertificateError();
+ bool answered() const;
+
+ QList<QSslCertificate> chain() const;
+
private:
- Q_DISABLE_COPY(QWebEngineCertificateError)
- Q_DECLARE_PRIVATE(QWebEngineCertificateError)
- QScopedPointer<QWebEngineCertificateErrorPrivate> d_ptr;
+ friend class QWebEnginePagePrivate;
+ QWebEngineCertificateError(const QSharedPointer<CertificateErrorController> &controller);
+ QExplicitlySharedDataPointer<QWebEngineCertificateErrorPrivate> d;
};
QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.cpp b/src/webenginewidgets/api/qwebenginedownloaditem.cpp
index 05c6956ea..e1bfc506f 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem.cpp
+++ b/src/webenginewidgets/api/qwebenginedownloaditem.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -43,6 +43,7 @@
#include "profile_adapter.h"
#include "qwebengineprofile_p.h"
+#include <QDir>
#include "QFileInfo"
QT_BEGIN_NAMESPACE
@@ -123,8 +124,9 @@ static inline QWebEngineDownloadItem::DownloadInterruptReason toDownloadInterrup
then the download request will be automatically rejected and nothing will be
written to disk.
- \note Some properties, like the \l path under which the file will be saved,
- can only be changed before calling accept().
+ \note Some properties, such as setting the path and file name where the file
+ will be saved (see \l downloadDirectory() and \l downloadFileName()), can
+ only be changed before calling accept().
\section2 Object Life Cycle
@@ -508,6 +510,11 @@ QString QWebEngineDownloadItem::mimeType() const
}
/*!
+ \obsolete
+
+ Use \l suggestedFileName(), \l downloadDirectory(), and
+ \l downloadFileName() instead.
+
Returns the full target path where data is being downloaded to.
The path includes the file name. The default suggested path is the standard download location
@@ -517,10 +524,14 @@ QString QWebEngineDownloadItem::mimeType() const
QString QWebEngineDownloadItem::path() const
{
Q_D(const QWebEngineDownloadItem);
- return d->downloadPath;
+ return QDir::cleanPath(QDir(d->downloadDirectory).filePath(d->downloadFileName));
}
/*!
+ \obsolete
+
+ Use \l setDownloadDirectory() and \l setDownloadFileName() instead.
+
Sets the full target path to download the file to.
The \a path should also include the file name. The download path can only be set in response
@@ -534,18 +545,109 @@ void QWebEngineDownloadItem::setPath(QString path)
qWarning("Setting the download path is not allowed after the download has been accepted.");
return;
}
+ if (QDir(d->downloadDirectory).filePath(d->downloadFileName) != path) {
+ if (QFileInfo(path).fileName().isEmpty()) {
+ qWarning("The download path does not include file name.");
+ return;
+ }
+
+ if (QFileInfo(path).isDir()) {
+ qWarning("The download path matches with an already existing directory path.");
+ return;
+ }
+
+ if (QFileInfo(path).fileName() == path) {
+ d->downloadDirectory = QStringLiteral("");
+ d->downloadFileName = path;
+ } else {
+ d->downloadDirectory = QFileInfo(path).path();
+ d->downloadFileName = QFileInfo(path).fileName();
+ }
+ }
+}
+
+/*!
+ \since 5.14
+
+ Returns the download directory path.
+*/
+
+QString QWebEngineDownloadItem::downloadDirectory() const
+{
+ Q_D(const QWebEngineDownloadItem);
+ return d->downloadDirectory;
+}
- if (QFileInfo(path).fileName().isEmpty()) {
- qWarning("The download path does not include file name.");
+/*!
+ \since 5.14
+
+ Sets \a directory as the directory path to download the file to.
+
+ The download directory path can only be set in response to the QWebEngineProfile::downloadRequested()
+ signal before the download is accepted. Past that point, this function has no effect on the
+ download item's state.
+*/
+
+void QWebEngineDownloadItem::setDownloadDirectory(QString directory)
+{
+ Q_D(QWebEngineDownloadItem);
+ if (d->downloadState != QWebEngineDownloadItem::DownloadRequested) {
+ qWarning("Setting the download directory is not allowed after the download has been accepted.");
return;
- }
+ }
+
+ if (!directory.isEmpty() && d->downloadDirectory != directory)
+ d->downloadDirectory = directory;
- if (QFileInfo(path).isDir()) {
- qWarning("The download path matches with an already existing directory path.");
+ d->downloadFileName = QFileInfo(d->profile->profileAdapter()->updateDownloadPath(d->downloadId,
+ d->downloadDirectory,
+ d->suggestedFileName)).fileName();
+}
+
+/*!
+ \since 5.14
+
+ Returns the file name to download the file to.
+*/
+
+QString QWebEngineDownloadItem::downloadFileName() const
+{
+ Q_D(const QWebEngineDownloadItem);
+ return d->downloadFileName;
+}
+
+/*!
+ \since 5.14
+
+ Sets \a fileName as the file name to download the file to.
+
+ The download file name can only be set in response to the QWebEngineProfile::downloadRequested()
+ signal before the download is accepted. Past that point, this function has no effect on the
+ download item's state.
+*/
+
+void QWebEngineDownloadItem::setDownloadFileName(QString fileName)
+{
+ Q_D(QWebEngineDownloadItem);
+ if (d->downloadState != QWebEngineDownloadItem::DownloadRequested) {
+ qWarning("Setting the download file name is not allowed after the download has been accepted.");
return;
}
- d->downloadPath = path;
+ if (!fileName.isEmpty())
+ d->downloadFileName = fileName;
+}
+
+/*!
+ \since 5.14
+
+ Returns the suggested file name.
+*/
+
+QString QWebEngineDownloadItem::suggestedFileName() const
+{
+ Q_D(const QWebEngineDownloadItem);
+ return d->suggestedFileName;
}
/*!
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.h b/src/webenginewidgets/api/qwebenginedownloaditem.h
index 981a3c374..169d80553 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem.h
+++ b/src/webenginewidgets/api/qwebenginedownloaditem.h
@@ -118,8 +118,8 @@ public:
qint64 receivedBytes() const;
QUrl url() const;
QString mimeType() const;
- QString path() const;
- void setPath(QString path);
+ QString Q_DECL_DEPRECATED path() const;
+ void Q_DECL_DEPRECATED setPath(QString path);
bool isFinished() const;
bool isPaused() const;
SavePageFormat savePageFormat() const;
@@ -128,6 +128,11 @@ public:
DownloadInterruptReason interruptReason() const;
QString interruptReasonString() const;
bool isSavePageDownload() const;
+ QString suggestedFileName() const;
+ QString downloadDirectory() const;
+ void setDownloadDirectory(QString directory);
+ QString downloadFileName() const;
+ void setDownloadFileName(QString fileName);
QWebEnginePage *page() const;
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem_p.h b/src/webenginewidgets/api/qwebenginedownloaditem_p.h
index b3bc8a3fe..08e478736 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem_p.h
+++ b/src/webenginewidgets/api/qwebenginedownloaditem_p.h
@@ -78,6 +78,9 @@ public:
const QUrl downloadUrl;
QString mimeType;
bool downloadPaused;
+ QString suggestedFileName;
+ QString downloadDirectory;
+ QString downloadFileName;
qint64 totalBytes;
qint64 receivedBytes;
diff --git a/src/webenginewidgets/api/qwebenginehistory.cpp b/src/webenginewidgets/api/qwebenginehistory.cpp
index 34279b016..6a85b984e 100644
--- a/src/webenginewidgets/api/qwebenginehistory.cpp
+++ b/src/webenginewidgets/api/qwebenginehistory.cpp
@@ -191,13 +191,13 @@ QList<QWebEngineHistoryItem> QWebEngineHistory::forwardItems(int maxItems) const
bool QWebEngineHistory::canGoBack() const
{
Q_D(const QWebEngineHistory);
- return d->page->webContents()->canGoBack();
+ return d->page->webContents()->canGoToOffset(-1);
}
bool QWebEngineHistory::canGoForward() const
{
Q_D(const QWebEngineHistory);
- return d->page->webContents()->canGoForward();
+ return d->page->webContents()->canGoToOffset(1);
}
void QWebEngineHistory::back()
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 7b66ac876..e4f4c4bc8 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -45,12 +45,14 @@
#include "certificate_error_controller.h"
#include "color_chooser_controller.h"
#include "favicon_manager.h"
+#include "find_text_helper.h"
#include "file_picker_controller.h"
#include "javascript_dialog_controller.h"
#if QT_CONFIG(webengine_printing_and_pdf)
#include "printer_worker.h"
#endif
#include "qwebenginecertificateerror.h"
+#include "qwebenginefindtextresult.h"
#include "qwebenginefullscreenrequest.h"
#include "qwebenginehistory.h"
#include "qwebenginehistory_p.h"
@@ -170,8 +172,9 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
qRegisterMetaType<QWebEngineQuotaRequest>();
qRegisterMetaType<QWebEngineRegisterProtocolHandlerRequest>();
+ qRegisterMetaType<QWebEngineFindTextResult>();
- // See wasShown() and wasHidden().
+ // See setVisible().
wasShownTimer.setSingleShot(true);
QObject::connect(&wasShownTimer, &QTimer::timeout, [this](){
ensureInitialized();
@@ -213,9 +216,8 @@ void QWebEnginePagePrivate::initializationFinished()
adapter->setAudioMuted(defaultAudioMuted);
if (!qFuzzyCompare(adapter->currentZoomFactor(), defaultZoomFactor))
adapter->setZoomFactor(defaultZoomFactor);
-
- if (view && view->isVisible())
- adapter->wasShown();
+ if (view)
+ adapter->setVisible(view->isVisible());
scriptCollection.d->initializationFinished(adapter);
@@ -260,7 +262,10 @@ void QWebEnginePagePrivate::didUpdateTargetURL(const QUrl &hoveredUrl)
void QWebEnginePagePrivate::selectionChanged()
{
Q_Q(QWebEnginePage);
- QTimer::singleShot(0, q, &QWebEnginePage::selectionChanged);
+ QTimer::singleShot(0, q, [this, q]() {
+ updateEditActions();
+ Q_EMIT q->selectionChanged();
+ });
}
void QWebEnginePagePrivate::recentlyAudibleChanged(bool recentlyAudible)
@@ -288,6 +293,7 @@ void QWebEnginePagePrivate::loadStarted(const QUrl &provisionalUrl, bool isError
return;
isLoading = true;
+ m_certificateErrorControllers.clear();
QTimer::singleShot(0, q, &QWebEnginePage::loadStarted);
}
@@ -417,11 +423,6 @@ void QWebEnginePagePrivate::didFetchDocumentInnerText(quint64 requestId, const Q
m_callbacks.invoke(requestId, result);
}
-void QWebEnginePagePrivate::didFindText(quint64 requestId, int matchCount)
-{
- m_callbacks.invoke(requestId, matchCount > 0);
-}
-
void QWebEnginePagePrivate::didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result)
{
#if QT_CONFIG(webengine_printing_and_pdf)
@@ -577,10 +578,10 @@ void QWebEnginePagePrivate::updateAction(QWebEnginePage::WebAction action) const
switch (action) {
case QWebEnginePage::Back:
- enabled = adapter->canGoBack();
+ enabled = adapter->canGoToOffset(-1);
break;
case QWebEnginePage::Forward:
- enabled = adapter->canGoForward();
+ enabled = adapter->canGoToOffset(1);
break;
case QWebEnginePage::Stop:
enabled = isLoading;
@@ -594,12 +595,14 @@ void QWebEnginePagePrivate::updateAction(QWebEnginePage::WebAction action) const
break;
case QWebEnginePage::Cut:
case QWebEnginePage::Copy:
+ case QWebEnginePage::Unselect:
+ enabled = adapter->hasFocusedFrame() && !adapter->selectedText().isEmpty();
+ break;
case QWebEnginePage::Paste:
case QWebEnginePage::Undo:
case QWebEnginePage::Redo:
case QWebEnginePage::SelectAll:
case QWebEnginePage::PasteAndMatchStyle:
- case QWebEnginePage::Unselect:
enabled = adapter->hasFocusedFrame();
break;
default:
@@ -651,8 +654,6 @@ void QWebEnginePagePrivate::recreateFromSerializedHistory(QDataStream &input)
adapter = std::move(newWebContents);
adapter->setClient(this);
adapter->loadDefault();
- if (view && view->isVisible())
- wasShown();
}
}
@@ -699,6 +700,12 @@ void QWebEnginePagePrivate::widgetChanged(RenderWidgetHostViewQtDelegate *newWid
bindPageAndWidget(q, static_cast<RenderWidgetHostViewQtDelegateWidget *>(newWidgetBase));
}
+void QWebEnginePagePrivate::findTextFinished(const QWebEngineFindTextResult &result)
+{
+ Q_Q(QWebEnginePage);
+ Q_EMIT q->findTextFinished(result);
+}
+
void QWebEnginePagePrivate::ensureInitialized() const
{
if (!adapter->isInitialized())
@@ -799,6 +806,16 @@ QWebEnginePage::QWebEnginePage(QObject* parent)
}
/*!
+ \fn void QWebEnginePage::findTextFinished(const QWebEngineFindTextResult &result)
+ \since 5.14
+
+ This signal is emitted when a search string search on a page is completed. \a result is
+ the result of the string search.
+
+ \sa findText()
+*/
+
+/*!
\fn void QWebEnginePage::printRequested()
\since 5.12
@@ -960,7 +977,6 @@ QWebEnginePage::~QWebEnginePage()
if (d_ptr) {
// d_ptr might be exceptionally null if profile adapter got deleted first
setDevToolsPage(nullptr);
- d_ptr->adapter->stopFinding();
QWebEnginePagePrivate::bindPageAndView(this, nullptr);
QWebEnginePagePrivate::bindPageAndWidget(this, nullptr);
}
@@ -1344,10 +1360,10 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
const QtWebEngineCore::WebEngineContextMenuData *menuData = d->contextData.d;
switch (action) {
case Back:
- d->adapter->navigateToOffset(-1);
+ d->adapter->navigateBack();
break;
case Forward:
- d->adapter->navigateToOffset(1);
+ d->adapter->navigateForward();
break;
case Stop:
d->adapter->stop();
@@ -1589,16 +1605,11 @@ void QWebEnginePage::findText(const QString &subString, FindFlags options, const
{
Q_D(QWebEnginePage);
if (!d->adapter->isInitialized()) {
- d->m_callbacks.invokeEmpty(resultCallback);
+ QtWebEngineCore::CallbackDirectory().invokeEmpty(resultCallback);
return;
}
- if (subString.isEmpty()) {
- d->adapter->stopFinding();
- d->m_callbacks.invokeEmpty(resultCallback);
- } else {
- quint64 requestId = d->adapter->findText(subString, options & FindCaseSensitively, options & FindBackward);
- d->m_callbacks.registerCallback(requestId, resultCallback);
- }
+
+ d->adapter->findTextHelper()->startFinding(subString, options & FindCaseSensitively, options & FindBackward, resultCallback);
}
/*!
@@ -1609,31 +1620,6 @@ bool QWebEnginePage::event(QEvent *e)
return QObject::event(e);
}
-void QWebEnginePagePrivate::wasShown()
-{
- if (!adapter->isInitialized()) {
- // On the one hand, it is too early to initialize here. The application
- // may call show() before load(), or it may call show() from
- // createWindow(), and then we would create an unnecessary blank
- // WebContents here. On the other hand, if the application calls show()
- // then it expects something to be shown, so we have to initialize.
- // Therefore we have to delay the initialization via the event loop.
- wasShownTimer.start();
- return;
- }
- adapter->wasShown();
-}
-
-void QWebEnginePagePrivate::wasHidden()
-{
- if (!adapter->isInitialized()) {
- // Cancel timer from wasShown() above.
- wasShownTimer.stop();
- return;
- }
- adapter->wasHidden();
-}
-
void QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData &data)
{
#if QT_CONFIG(action)
@@ -1674,8 +1660,8 @@ void QWebEnginePagePrivate::navigationRequested(int navigationType, const QUrl &
{
Q_Q(QWebEnginePage);
bool accepted = q->acceptNavigationRequest(url, static_cast<QWebEnginePage::NavigationType>(navigationType), isMainFrame);
- if (accepted && adapter->isFindTextInProgress())
- adapter->stopFinding();
+ if (accepted && adapter->findTextHelper()->isFindTextInProgress())
+ adapter->findTextHelper()->stopFinding();
navigationRequestAction = accepted ? WebContentsAdapterClient::AcceptRequest : WebContentsAdapterClient::IgnoreRequest;
}
@@ -1729,9 +1715,12 @@ void QWebEnginePagePrivate::allowCertificateError(const QSharedPointer<Certifica
Q_Q(QWebEnginePage);
bool accepted = false;
- QWebEngineCertificateError error(controller->error(), controller->url(), controller->overridable(), controller->errorString());
+ QWebEngineCertificateError error(controller);
accepted = q->certificateError(error);
- controller->accept(error.isOverridable() && accepted);
+ if (error.deferred() && !error.answered())
+ m_certificateErrorControllers.append(controller);
+ else if (!error.answered())
+ controller->accept(error.isOverridable() && accepted);
}
void QWebEnginePagePrivate::selectClientCert(const QSharedPointer<ClientCertSelectController> &controller)
@@ -1842,6 +1831,26 @@ void QWebEnginePagePrivate::printRequested()
});
}
+void QWebEnginePagePrivate::lifecycleStateChanged(LifecycleState state)
+{
+ Q_Q(QWebEnginePage);
+ Q_EMIT q->lifecycleStateChanged(static_cast<QWebEnginePage::LifecycleState>(state));
+}
+
+void QWebEnginePagePrivate::recommendedStateChanged(LifecycleState state)
+{
+ Q_Q(QWebEnginePage);
+ QTimer::singleShot(0, q, [q, state]() {
+ Q_EMIT q->recommendedStateChanged(static_cast<QWebEnginePage::LifecycleState>(state));
+ });
+}
+
+void QWebEnginePagePrivate::visibleChanged(bool visible)
+{
+ Q_Q(QWebEnginePage);
+ Q_EMIT q->visibleChanged(visible);
+}
+
/*!
\since 5.13
@@ -2127,6 +2136,10 @@ void QWebEnginePage::runJavaScript(const QString &scriptSource)
{
Q_D(QWebEnginePage);
d->ensureInitialized();
+ if (d->adapter->lifecycleState() == WebContentsAdapter::LifecycleState::Discarded) {
+ qWarning("runJavaScript: disabled in Discarded state");
+ return;
+ }
d->adapter->runJavaScript(scriptSource, QWebEngineScript::MainWorld);
}
@@ -2134,6 +2147,11 @@ void QWebEnginePage::runJavaScript(const QString& scriptSource, const QWebEngine
{
Q_D(QWebEnginePage);
d->ensureInitialized();
+ if (d->adapter->lifecycleState() == WebContentsAdapter::LifecycleState::Discarded) {
+ qWarning("runJavaScript: disabled in Discarded state");
+ d->m_callbacks.invokeEmpty(resultCallback);
+ return;
+ }
quint64 requestId = d->adapter->runJavaScriptCallbackResult(scriptSource, QWebEngineScript::MainWorld);
d->m_callbacks.registerCallback(requestId, resultCallback);
}
@@ -2512,6 +2530,120 @@ const QWebEngineContextMenuData &QWebEnginePage::contextMenuData() const
return d->contextData;
}
+/*!
+ \enum QWebEnginePage::LifecycleState
+ \since 5.14
+
+ This enum describes the lifecycle state of the page:
+
+ \value Active
+ Normal state.
+ \value Frozen
+ Low CPU usage state where most HTML task sources are suspended.
+ \value Discarded
+ Very low resource usage state where the entire browsing context is discarded.
+
+ \sa lifecycleState, {WebEngine Lifecycle Example}
+*/
+
+/*!
+ \property QWebEnginePage::lifecycleState
+ \since 5.14
+
+ \brief The current lifecycle state of the page.
+
+ The following restrictions are enforced by the setter:
+
+ \list
+ \li A \l{visible} page must remain in the \c{Active} state.
+ \li If the page is being inspected by a \l{devToolsPage} then both pages must
+ remain in the \c{Active} states.
+ \li A page in the \c{Discarded} state can only transition to the \c{Active}
+ state. This will cause a reload of the page.
+ \endlist
+
+ These are the only hard limits on the lifecycle state, but see also
+ \l{recommendedState} for the recommended soft limits.
+
+ \sa recommendedState, {WebEngine Lifecycle Example}
+*/
+
+QWebEnginePage::LifecycleState QWebEnginePage::lifecycleState() const
+{
+ Q_D(const QWebEnginePage);
+ return static_cast<LifecycleState>(d->adapter->lifecycleState());
+}
+
+void QWebEnginePage::setLifecycleState(LifecycleState state)
+{
+ Q_D(QWebEnginePage);
+ d->adapter->setLifecycleState(static_cast<WebContentsAdapterClient::LifecycleState>(state));
+}
+
+/*!
+ \property QWebEnginePage::recommendedState
+ \since 5.14
+
+ \brief The recommended limit for the lifecycle state of the page.
+
+ Setting the lifecycle state to a lower resource usage state than the
+ recommended state may cause side-effects such as stopping background audio
+ playback or loss of HTML form input. Setting the lifecycle state to a higher
+ resource state is however completely safe.
+
+ \sa lifecycleState
+*/
+
+QWebEnginePage::LifecycleState QWebEnginePage::recommendedState() const
+{
+ Q_D(const QWebEnginePage);
+ return static_cast<LifecycleState>(d->adapter->recommendedState());
+}
+
+/*!
+ \property QWebEnginePage::visible
+ \since 5.14
+
+ \brief Whether the page is considered visible in the Page Visibility API.
+
+ Setting this property changes the \c{Document.hidden} and the
+ \c{Document.visibilityState} properties in JavaScript which web sites can use
+ to voluntarily reduce their resource usage if they are not visible to the
+ user.
+
+ If the page is connected to a \l{view} then this property will be managed
+ automatically by the view according to it's own visibility.
+
+ \sa lifecycleState
+*/
+
+bool QWebEnginePage::isVisible() const
+{
+ Q_D(const QWebEnginePage);
+ return d->adapter->isVisible();
+}
+
+void QWebEnginePage::setVisible(bool visible)
+{
+ Q_D(QWebEnginePage);
+
+ if (!d->adapter->isInitialized()) {
+ // On the one hand, it is too early to initialize here. The application
+ // may call show() before load(), or it may call show() from
+ // createWindow(), and then we would create an unnecessary blank
+ // WebContents here. On the other hand, if the application calls show()
+ // then it expects something to be shown, so we have to initialize.
+ // Therefore we have to delay the initialization via the event loop.
+ if (visible)
+ d->wasShownTimer.start();
+ else
+ d->wasShownTimer.stop();
+ return;
+ }
+
+ d->adapter->setVisible(visible);
+}
+
#if QT_CONFIG(action)
QContextMenuBuilder::QContextMenuBuilder(const QtWebEngineCore::WebEngineContextMenuData &data,
QWebEnginePage *page,
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index 4956877a9..cd012ea70 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -62,6 +62,7 @@ class QWebChannel;
class QWebEngineCertificateError;
class QWebEngineClientCertificateSelection;
class QWebEngineContextMenuData;
+class QWebEngineFindTextResult;
class QWebEngineFullScreenRequest;
class QWebEngineHistory;
class QWebEnginePage;
@@ -88,6 +89,9 @@ class QWEBENGINEWIDGETS_EXPORT QWebEnginePage : public QObject {
Q_PROPERTY(QPointF scrollPosition READ scrollPosition NOTIFY scrollPositionChanged)
Q_PROPERTY(bool audioMuted READ isAudioMuted WRITE setAudioMuted NOTIFY audioMutedChanged)
Q_PROPERTY(bool recentlyAudible READ recentlyAudible NOTIFY recentlyAudibleChanged)
+ Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged)
+ Q_PROPERTY(LifecycleState lifecycleState READ lifecycleState WRITE setLifecycleState NOTIFY lifecycleStateChanged)
+ Q_PROPERTY(LifecycleState recommendedState READ recommendedState NOTIFY recommendedStateChanged)
public:
enum WebAction {
@@ -180,7 +184,8 @@ public:
NavigationTypeFormSubmitted,
NavigationTypeBackForward,
NavigationTypeReload,
- NavigationTypeOther
+ NavigationTypeOther,
+ NavigationTypeRedirect,
};
Q_ENUM(NavigationType)
@@ -221,6 +226,14 @@ public:
};
Q_ENUM(RenderProcessTerminationStatus)
+ // must match WebContentsAdapterClient::LifecycleState
+ enum class LifecycleState {
+ Active,
+ Frozen,
+ Discarded,
+ };
+ Q_ENUM(LifecycleState)
+
explicit QWebEnginePage(QObject *parent = Q_NULLPTR);
QWebEnginePage(QWebEngineProfile *profile, QObject *parent = Q_NULLPTR);
~QWebEnginePage();
@@ -306,6 +319,14 @@ public:
const QWebEngineContextMenuData &contextMenuData() const;
+ LifecycleState lifecycleState() const;
+ void setLifecycleState(LifecycleState state);
+
+ LifecycleState recommendedState() const;
+
+ bool isVisible() const;
+ void setVisible(bool visible);
+
Q_SIGNALS:
void loadStarted();
void loadProgress(int progress);
@@ -344,6 +365,13 @@ Q_SIGNALS:
void pdfPrintingFinished(const QString &filePath, bool success);
void printRequested();
+ void visibleChanged(bool visible);
+
+ void lifecycleStateChanged(LifecycleState state);
+ void recommendedStateChanged(LifecycleState state);
+
+ void findTextFinished(const QWebEngineFindTextResult &result);
+
protected:
virtual QWebEnginePage *createWindow(WebWindowType type);
virtual QStringList chooseFiles(FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes);
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index dc0ead534..2843f69c4 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -72,6 +72,7 @@ class WebContentsAdapter;
}
QT_BEGIN_NAMESPACE
+class QWebEngineFindTextResult;
class QWebEngineHistory;
class QWebEnginePage;
class QWebEngineProfile;
@@ -92,6 +93,9 @@ public:
QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override;
QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegateForPopup(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override { return CreateRenderWidgetHostViewQtDelegate(client); }
void initializationFinished() override;
+ void lifecycleStateChanged(LifecycleState state) override;
+ void recommendedStateChanged(LifecycleState state) override;
+ void visibleChanged(bool visible) override;
void titleChanged(const QString&) override;
void urlChanged(const QUrl&) override;
void iconChanged(const QUrl&) override;
@@ -124,7 +128,6 @@ public:
void didRunJavaScript(quint64 requestId, const QVariant& result) override;
void didFetchDocumentMarkup(quint64 requestId, const QString& result) override;
void didFetchDocumentInnerText(quint64 requestId, const QString& result) override;
- void didFindText(quint64 requestId, int matchCount) override;
void didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result) override;
void didPrintPageToPdf(const QString &filePath, bool success) override;
bool passOnFocus(bool reverse) override;
@@ -160,6 +163,7 @@ public:
ClientType clientType() override { return QtWebEngineCore::WebContentsAdapterClient::WidgetsClient; }
void interceptRequest(QWebEngineUrlRequestInfo &) override;
void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegate *newWidget) override;
+ void findTextFinished(const QWebEngineFindTextResult &result) override;
QtWebEngineCore::ProfileAdapter *profileAdapter() override;
QtWebEngineCore::WebContentsAdapter *webContentsAdapter() override;
@@ -167,9 +171,6 @@ public:
void updateAction(QWebEnginePage::WebAction) const;
void _q_webActionTriggered(bool checked);
- void wasShown();
- void wasHidden();
-
QtWebEngineCore::WebContentsAdapter *webContents() { return adapter.data(); }
void recreateFromSerializedHistory(QDataStream &input);
@@ -209,6 +210,8 @@ public:
#if QT_CONFIG(webengine_printing_and_pdf)
QPrinter *currentPrinter;
#endif
+
+ QList<QSharedPointer<CertificateErrorController>> m_certificateErrorControllers;
};
class QContextMenuBuilder : public QtWebEngineCore::RenderViewContextMenuQt
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index f9fcc6136..09f5ce2fd 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -53,6 +53,7 @@
#include "visited_links_manager_qt.h"
#include "web_engine_settings.h"
+#include <QDir>
#include <QtWebEngineCore/qwebengineurlscheme.h>
QT_BEGIN_NAMESPACE
@@ -100,7 +101,7 @@ using QtWebEngineCore::ProfileAdapter;
web pages not specifically created with another profile belong to.
Implementing the QWebEngineUrlRequestInterceptor interface and registering the interceptor on a
- profile by setRequestInterceptor() enables intercepting, blocking, and modifying URL
+ profile by setUrlRequestInterceptor() enables intercepting, blocking, and modifying URL
requests (QWebEngineUrlRequestInfo) before they reach the networking stack of Chromium.
A QWebEngineUrlSchemeHandler can be registered for a profile by installUrlSchemeHandler()
@@ -226,7 +227,9 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
itemPrivate->downloadId = info.id;
itemPrivate->downloadState = info.accepted ? QWebEngineDownloadItem::DownloadInProgress
: QWebEngineDownloadItem::DownloadRequested;
- itemPrivate->downloadPath = info.path;
+ itemPrivate->downloadDirectory = QFileInfo(info.path).path();
+ itemPrivate->downloadFileName = QFileInfo(info.path).fileName();
+ itemPrivate->suggestedFileName = info.suggestedFileName;
itemPrivate->mimeType = info.mimeType;
itemPrivate->savePageFormat = static_cast<QWebEngineDownloadItem::SavePageFormat>(info.savePageFormat);
itemPrivate->type = static_cast<QWebEngineDownloadItem::DownloadType>(info.downloadType);
@@ -244,7 +247,7 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
QWebEngineDownloadItem::DownloadState state = download->state();
- info.path = download->path();
+ info.path = QDir(download->downloadDirectory()).filePath(download->downloadFileName());
info.savePageFormat = static_cast<QtWebEngineCore::ProfileAdapterClient::SavePageFormat>(
download->savePageFormat());
info.accepted = state != QWebEngineDownloadItem::DownloadCancelled;
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index 6e1138522..de81448a9 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -61,7 +61,7 @@ void QWebEngineViewPrivate::pageChanged(QWebEnginePage *oldPage, QWebEnginePage
Q_Q(QWebEngineView);
if (oldPage) {
- oldPage->d_ptr->wasHidden();
+ oldPage->setVisible(false);
oldPage->disconnect(q);
}
@@ -75,8 +75,7 @@ void QWebEngineViewPrivate::pageChanged(QWebEnginePage *oldPage, QWebEnginePage
QObject::connect(newPage, &QWebEnginePage::loadFinished, q, &QWebEngineView::loadFinished);
QObject::connect(newPage, &QWebEnginePage::selectionChanged, q, &QWebEngineView::selectionChanged);
QObject::connect(newPage, &QWebEnginePage::renderProcessTerminated, q, &QWebEngineView::renderProcessTerminated);
- if (q->isVisible())
- newPage->d_ptr->wasShown();
+ newPage->setVisible(q->isVisible());
}
auto oldUrl = oldPage ? oldPage->url() : QUrl();
@@ -381,7 +380,7 @@ void QWebEngineView::contextMenuEvent(QContextMenuEvent *event)
void QWebEngineView::showEvent(QShowEvent *event)
{
QWidget::showEvent(event);
- page()->d_ptr->wasShown();
+ page()->setVisible(true);
}
/*!
@@ -390,7 +389,17 @@ void QWebEngineView::showEvent(QShowEvent *event)
void QWebEngineView::hideEvent(QHideEvent *event)
{
QWidget::hideEvent(event);
- page()->d_ptr->wasHidden();
+ page()->setVisible(false);
+}
+
+/*!
+ * \reimp
+ */
+void QWebEngineView::closeEvent(QCloseEvent *event)
+{
+ QWidget::closeEvent(event);
+ page()->setVisible(false);
+ page()->setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
}
#if QT_CONFIG(draganddrop)
diff --git a/src/webenginewidgets/api/qwebengineview.h b/src/webenginewidgets/api/qwebengineview.h
index e3cb7ad75..63a68f46c 100644
--- a/src/webenginewidgets/api/qwebengineview.h
+++ b/src/webenginewidgets/api/qwebengineview.h
@@ -126,6 +126,7 @@ protected:
bool event(QEvent*) override;
void showEvent(QShowEvent *) override;
void hideEvent(QHideEvent *) override;
+ void closeEvent(QCloseEvent *) override;
#if QT_CONFIG(draganddrop)
void dragEnterEvent(QDragEnterEvent *e) override;
void dragLeaveEvent(QDragLeaveEvent *e) override;
diff --git a/src/webenginewidgets/configure.json b/src/webenginewidgets/configure.json
new file mode 100644
index 000000000..a27faf78d
--- /dev/null
+++ b/src/webenginewidgets/configure.json
@@ -0,0 +1,28 @@
+{
+ "module": "webenginewidgets",
+ "condition": "module.webenginecore && features.webengine-widgets",
+ "depends": [
+ "webenginecore-private"
+ ],
+ "commandline": {
+ "options": {
+ "webengine-widgets": "boolean"
+ }
+ },
+ "features": {
+ "webengine-widgets": {
+ "label": "Support Qt WebEngine Widgets",
+ "purpose": "Provides WebEngine Widgets support.",
+ "condition": "module.widgets",
+ "output": [ "privateFeature" ]
+ }
+ },
+ "summary": [
+ {
+ "section": "Qt WebEngineWidgets",
+ "entries": [
+ "webengine-widgets"
+ ]
+ }
+ ]
+}
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index e5c0c0c3e..7701b9b3d 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -276,6 +276,7 @@
\value NavigationTypeFormSubmitted The navigation request resulted from a form submission.
\value NavigationTypeBackForward The navigation request resulted from a back or forward action.
\value NavigationTypeReload The navigation request resulted from a reload action.
+ \value NavigationTypeRedirect The navigation request resulted from a content or server controlled redirect. This also includes automatic reloads. (Added in Qt 5.14)
\value NavigationTypeOther The navigation request was triggered by other means not covered by the above.
\sa acceptNavigationRequest()
@@ -488,6 +489,7 @@
/*!
\fn void QWebEnginePage::findText(const QString &subString, QWebEnginePage::FindFlags options = FindFlags(), const QWebEngineCallback<bool> &resultCallback = QWebEngineCallback<bool>())
Finds the specified string, \a subString, in the page, using the given \a options.
+ The findTextFinished() signal is emitted when a string search is completed.
To clear the search highlight, just pass an empty string.
@@ -500,13 +502,15 @@
For example:
\snippet qtwebengine_qwebenginepage_snippet.cpp 0
+
+ \sa findTextFinished()
*/
/*!
\fn QWebEngineSettings *QWebEnginePage::settings() const
Returns a pointer to the page's settings object.
- \sa QWebEngineSettings::globalSettings()
+ \sa QWebEngineSettings::defaultSettings()
*/
/*!
@@ -518,6 +522,8 @@
Return \c true to ignore the error and complete the request. Return \c false to stop loading
the request.
+ \note If the error was successfully deferred then the returned value will be ignored.
+
\sa QWebEngineCertificateError
*/
diff --git a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
index ce75a4203..0706598ef 100644
--- a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
@@ -22,12 +22,14 @@
// by its LGPL license. Documentation written from scratch for new methods should be
// placed inline in the code as usual.
+#if QT_DEPRECATED_SINCE(5, 5)
/*!
\fn static QWebEngineSettings *QWebEngineSettings::globalSettings()
\obsolete
Use defaultSettings() instead.
*/
+#endif
/*!
\class QWebEngineSettings
diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
index 1b7812dff..3f1b6e509 100644
--- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
@@ -393,5 +393,5 @@
\snippet qtwebengine_qwebengineview_snippet.cpp 6
- \sa QWebEngineSettings::globalSettings()
+ \sa QWebEngineSettings::defaultSettings()
*/
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
index 88eb9843b..894dca4fa 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -301,12 +301,6 @@ QSGLayer *RenderWidgetHostViewQtDelegateWidget::createLayer()
return renderContext->sceneGraphContext()->createLayer(renderContext);
}
-QSGInternalImageNode *RenderWidgetHostViewQtDelegateWidget::createInternalImageNode()
-{
- QSGRenderContext *renderContext = QQuickWindowPrivate::get(quickWindow())->context;
- return renderContext->sceneGraphContext()->createInternalImageNode();
-}
-
QSGImageNode *RenderWidgetHostViewQtDelegateWidget::createImageNode()
{
return quickWindow()->createImageNode();
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
index 7746c4405..18f848da5 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
@@ -78,7 +78,6 @@ public:
QWindow* window() const override;
QSGTexture *createTextureFromImage(const QImage &) override;
QSGLayer *createLayer() override;
- QSGInternalImageNode *createInternalImageNode() override;
QSGImageNode *createImageNode() override;
QSGRectangleNode *createRectangleNode() override;
void update() override;