diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-09-18 10:15:51 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-09-18 10:16:01 +0200 |
commit | fa179ff4ca2fdd07cce2aeb0780be202c57f2995 (patch) | |
tree | 18deb3579bcdf5e9e3584ac8505c610e7c7828aa /src | |
parent | 7b365eb352780dc0d939e918b0aa58d0458fd9da (diff) | |
parent | 56474df111738070f6c55d3712ec07565239bad8 (diff) |
Merge branch '5.10' into dev
Change-Id: If9b7ec5e67a49aa017b49b75d7ccf6d45820f72e
Diffstat (limited to 'src')
74 files changed, 1343 insertions, 823 deletions
diff --git a/src/3rdparty b/src/3rdparty -Subproject 582c5493439ba9ac57c6c14c706f530741f5bfc +Subproject d23df0c25c334dbde96ef5eb65cc098eee47859 diff --git a/src/buildtools/gn.pro b/src/buildtools/gn.pro index 829e7a31a..db4bbf82c 100644 --- a/src/buildtools/gn.pro +++ b/src/buildtools/gn.pro @@ -19,7 +19,14 @@ build_pass|!debug_and_release { mkpath($$dirname(out)) src_3rd_party_dir = $$absolute_path("$${getChromiumSrcDir()}/../", "$$QTWEBENGINE_ROOT") gn_bootstrap = $$system_path($$absolute_path(chromium/tools/gn/bootstrap/bootstrap.py, $$src_3rd_party_dir)) + gn_args = $$system_quote($$gn_args) + win32:isDeveloperBuild() { + # GN is always built in release mode, which conflicts with incremental linking when + # doing a developer build of WebEngine. + gn_args = $$replace(gn_args, "use_incremental_linking=true ", "") + } + gn_configure = $$system_quote($$gn_bootstrap) --shadow --gn-gen-args=$$gn_args $$ninja_path !system("cd $$system_quote($$system_path($$dirname(out))) && $$pythonPathForSystem() $$gn_configure") { error("GN build error!") diff --git a/src/core/api/qwebengineurlrequestjob.cpp b/src/core/api/qwebengineurlrequestjob.cpp index 1db23f6ab..a071adbd5 100644 --- a/src/core/api/qwebengineurlrequestjob.cpp +++ b/src/core/api/qwebengineurlrequestjob.cpp @@ -39,6 +39,7 @@ #include "qwebengineurlrequestjob.h" +#include "url_request_custom_job_proxy.h" #include "url_request_custom_job_delegate.h" using QtWebEngineCore::URLRequestCustomJobDelegate; @@ -114,10 +115,16 @@ QByteArray QWebEngineUrlRequestJob::requestMethod() const /*! Replies to the request with \a device and the MIME type \a contentType. + The user has to be aware that \a device will be used on another thread + until the job is deleted. In case simultaneous access from the main thread + is desired, the user is reponsible for making access to \a device thread-safe + for example by using QMutex. Note that the \a device object is not owned by + the web engine. Therefore, the signal QObject::destroyed() of + QWebEngineUrlRequestJob must be monitored. */ void QWebEngineUrlRequestJob::reply(const QByteArray &contentType, QIODevice *device) { - d_ptr->setReply(contentType, device); + d_ptr->reply(contentType, device); } /*! diff --git a/src/core/api/qwebengineurlrequestjob.h b/src/core/api/qwebengineurlrequestjob.h index afa542d7e..4f23ab401 100644 --- a/src/core/api/qwebengineurlrequestjob.h +++ b/src/core/api/qwebengineurlrequestjob.h @@ -48,7 +48,7 @@ namespace QtWebEngineCore { class URLRequestCustomJobDelegate; -class URLRequestCustomJobShared; +class URLRequestCustomJobProxy; } // namespace QT_BEGIN_NAMESPACE @@ -79,7 +79,7 @@ public: private: QWebEngineUrlRequestJob(QtWebEngineCore::URLRequestCustomJobDelegate *); - friend class QtWebEngineCore::URLRequestCustomJobShared; + friend class QtWebEngineCore::URLRequestCustomJobProxy; QtWebEngineCore::URLRequestCustomJobDelegate* d_ptr; }; diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp index 7dad00f65..b718ed3bf 100644 --- a/src/core/browser_accessibility_qt.cpp +++ b/src/core/browser_accessibility_qt.cpp @@ -127,7 +127,7 @@ void *BrowserAccessibilityQt::interface_cast(QAccessible::InterfaceType type) QAccessibleInterface *BrowserAccessibilityQt::parent() const { - BrowserAccessibility *p = GetParent(); + BrowserAccessibility *p = PlatformGetParent(); if (p) return static_cast<BrowserAccessibilityQt*>(p); return static_cast<BrowserAccessibilityManagerQt*>(manager())->rootParentAccessible(); @@ -261,7 +261,7 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::NoRole; // FIXME case ui::AX_ROLE_DISCLOSURE_TRIANGLE: return QAccessible::NoRole; // FIXME - case ui::AX_ROLE_DIV: + case ui::AX_ROLE_GENERIC_CONTAINER: return QAccessible::Section; case ui::AX_ROLE_DOCUMENT: return QAccessible::Document; @@ -454,7 +454,7 @@ QAccessible::State BrowserAccessibilityQt::state() const int32_t s = GetState(); if (s & (1 << ui::AX_STATE_BUSY)) state.busy = true; - if (s & (1 << ui::AX_STATE_CHECKED)) + if (s & (1 << ui::AX_CHECKED_STATE_TRUE)) state.checked = true; if (s & (1 << ui::AX_STATE_COLLAPSED)) state.collapsed = true; @@ -830,9 +830,9 @@ bool BrowserAccessibilityQt::isSelected() const QAccessibleInterface *BrowserAccessibilityQt::table() const { - BrowserAccessibility* find_table = GetParent(); + BrowserAccessibility* find_table = PlatformGetParent(); while (find_table && find_table->GetRole() != ui::AX_ROLE_TABLE) - find_table = find_table->GetParent(); + find_table = find_table->PlatformGetParent(); if (!find_table) return 0; return static_cast<BrowserAccessibilityQt*>(find_table); diff --git a/src/core/browser_context_qt.cpp b/src/core/browser_context_qt.cpp index ffee001ff..16b7e5514 100644 --- a/src/core/browser_context_qt.cpp +++ b/src/core/browser_context_qt.cpp @@ -57,7 +57,7 @@ #include "base/base_paths.h" #include "components/prefs/pref_member.h" #include "components/prefs/pref_service.h" -#include "components/prefs/testing_pref_store.h" +#include "components/prefs/in_memory_pref_store.h" #include "components/prefs/pref_service.h" #include "components/prefs/pref_service_factory.h" #include "components/prefs/pref_registry_simple.h" @@ -72,9 +72,8 @@ namespace QtWebEngineCore { BrowserContextQt::BrowserContextQt(BrowserContextAdapter *adapter) : m_adapter(adapter), - m_prefStore(new TestingPrefStore()) + m_prefStore(new InMemoryPrefStore()) { - m_prefStore->SetInitializationCompleted(); PrefServiceFactory factory; factory.set_user_prefs(m_prefStore); scoped_refptr<PrefRegistrySimple> registry(new PrefRegistrySimple()); @@ -82,7 +81,7 @@ BrowserContextQt::BrowserContextQt(BrowserContextAdapter *adapter) #if BUILDFLAG(ENABLE_SPELLCHECK) // Initial spellcheck settings registry->RegisterStringPref(prefs::kAcceptLanguages, std::string()); - registry->RegisterListPref(spellcheck::prefs::kSpellCheckDictionaries, new base::ListValue()); + registry->RegisterListPref(spellcheck::prefs::kSpellCheckDictionaries, base::MakeUnique<base::ListValue>()); registry->RegisterStringPref(spellcheck::prefs::kSpellCheckDictionary, std::string()); registry->RegisterBooleanPref(spellcheck::prefs::kEnableSpellcheck, false); registry->RegisterBooleanPref(spellcheck::prefs::kSpellCheckUseSpellingService, false); @@ -206,7 +205,7 @@ net::URLRequestContextGetter *BrowserContextQt::CreateRequestContextForStoragePa } #if BUILDFLAG(ENABLE_SPELLCHECK) -void BrowserContextQt::failedToLoadDictionary(const std::string &language) +void BrowserContextQt::FailedToLoadDictionary(const std::string &language) { Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); qWarning() << "Could not load dictionary for:" << toQt(language) << endl @@ -229,7 +228,7 @@ QStringList BrowserContextQt::spellCheckLanguages() const QStringList spellcheck_dictionaries; for (const auto &value : *m_prefService->GetList(spellcheck::prefs::kSpellCheckDictionaries)) { std::string dictionary; - if (value->GetAsString(&dictionary)) + if (value.GetAsString(&dictionary)) spellcheck_dictionaries.append(QString::fromStdString(dictionary)); } diff --git a/src/core/browser_context_qt.h b/src/core/browser_context_qt.h index af250f506..681657d96 100644 --- a/src/core/browser_context_qt.h +++ b/src/core/browser_context_qt.h @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE class QStringList; QT_END_NAMESPACE -class TestingPrefStore; +class InMemoryPrefStore; class PrefService; namespace QtWebEngineCore { @@ -100,7 +100,7 @@ public: BrowserContextAdapter *adapter() { return m_adapter; } #if BUILDFLAG(ENABLE_SPELLCHECK) - void failedToLoadDictionary(const std::string& language) override; + void FailedToLoadDictionary(const std::string& language) override; void setSpellCheckLanguages(const QStringList &languages); QStringList spellCheckLanguages() const; void setSpellCheckEnabled(bool enabled); @@ -115,7 +115,7 @@ private: std::unique_ptr<PermissionManagerQt> permissionManager; std::unique_ptr<SSLHostStateDelegateQt> sslHostStateDelegate; BrowserContextAdapter *m_adapter; - scoped_refptr<TestingPrefStore> m_prefStore; + scoped_refptr<InMemoryPrefStore> m_prefStore; std::unique_ptr<PrefService> m_prefService; friend class BrowserContextAdapter; diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp index 9d2ff4c0e..997c7ba43 100644 --- a/src/core/clipboard_qt.cpp +++ b/src/core/clipboard_qt.cpp @@ -352,13 +352,20 @@ SkBitmap ClipboardQt::ReadImage(ui::ClipboardType type) const image = image.convertToFormat(QImage::Format_ARGB32); SkBitmap bitmap; - bitmap.setInfo(SkImageInfo::MakeN32(image.width(), image.height(), kOpaque_SkAlphaType)); - bitmap.setPixels(const_cast<uchar*>(image.constBits())); - // Return a deep copy of the pixel data. - SkBitmap copy; - bitmap.copyTo(©, kN32_SkColorType); - return copy; + bitmap.allocN32Pixels(image.width(), image.height(), true); + const size_t bytesPerRowDst = bitmap.rowBytes(); + const size_t bytesPerLineSrc = static_cast<size_t>(image.bytesPerLine()); + const size_t dataBytes = std::min(bytesPerRowDst, bytesPerLineSrc); + uchar *dst = static_cast<uchar *>(bitmap.getPixels()); + const uchar *src = image.constBits(); + for (int y = 0; y < image.height(); ++y) { + memcpy(dst, src, dataBytes); + dst += bytesPerRowDst; + src += bytesPerLineSrc; + } + + return bitmap; } void ClipboardQt::ReadCustomData(ui::ClipboardType clipboard_type, const base::string16& type, base::string16* result) const diff --git a/src/core/common/qt_messages.h b/src/core/common/qt_messages.h index d998db20e..00efa485e 100644 --- a/src/core/common/qt_messages.h +++ b/src/core/common/qt_messages.h @@ -43,11 +43,11 @@ IPC_MESSAGE_ROUTED1(WebChannelIPCTransport_Uninstall, uint /* worldId */) IPC_MESSAGE_ROUTED2(WebChannelIPCTransport_Message, std::vector<char> /*binaryJSON*/, uint /* worldId */) // User scripts messages -IPC_MESSAGE_ROUTED1(RenderViewObserverHelper_AddScript, +IPC_MESSAGE_ROUTED1(RenderFrameObserverHelper_AddScript, UserScriptData /* script */) -IPC_MESSAGE_ROUTED1(RenderViewObserverHelper_RemoveScript, +IPC_MESSAGE_ROUTED1(RenderFrameObserverHelper_RemoveScript, UserScriptData /* script */) -IPC_MESSAGE_ROUTED0(RenderViewObserverHelper_ClearScripts) +IPC_MESSAGE_ROUTED0(RenderFrameObserverHelper_ClearScripts) IPC_MESSAGE_CONTROL1(UserResourceController_AddScript, UserScriptData /* scriptContents */) IPC_MESSAGE_CONTROL1(UserResourceController_RemoveScript, UserScriptData /* scriptContents */) diff --git a/src/core/config/common.pri b/src/core/config/common.pri index b0723e333..ce7364ff9 100644 --- a/src/core/config/common.pri +++ b/src/core/config/common.pri @@ -4,14 +4,14 @@ gn_args += \ use_qt=true \ is_component_build=false \ is_shared=true \ - enable_media_router=false \ enable_nacl=false \ enable_remoting=false \ enable_web_speech=false \ - use_experimental_allocator_shim=false \ + use_allocator_shim=false \ use_allocator=\"none\" \ v8_use_external_startup_data=false \ - treat_warnings_as_errors=false + treat_warnings_as_errors=false \ + enable_swiftshader=false use?(printing) { gn_args += enable_basic_printing=true enable_print_preview=true @@ -55,6 +55,10 @@ CONFIG(release, debug|release) { } } +CONFIG(debug, debug|release) { + gn_args += use_debug_fission=false +} + !webcore_debug: gn_args += remove_webcore_debug_symbols=true !v8base_debug: gn_args += remove_v8base_debug_symbols=true diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri index 60cfa6857..c0f2f6289 100644 --- a/src/core/config/linux.pri +++ b/src/core/config/linux.pri @@ -41,7 +41,7 @@ cross_compile:!host_build { !isEmpty(TOOLCHAIN_SYSROOT): gn_args += target_sysroot=\"$${TOOLCHAIN_SYSROOT}\" } -contains(QT_ARCH, "arm"):!host_build { +contains(QT_ARCH, "arm") { # Extract ARM specific compiler options that we have to pass to gn, # but let gn figure out a default if an option is not present. MTUNE = $$extractCFlag("-mtune=.*") @@ -78,7 +78,7 @@ contains(QT_ARCH, "arm"):!host_build { else: contains(QMAKE_CFLAGS, "-mthumb"): gn_args += arm_use_thumb=true } -contains(QT_ARCH, "mips"):!host_build { +contains(QT_ARCH, "mips") { MARCH = $$extractCFlag("-march=.*") !isEmpty(MARCH) { equals(MARCH, "mips32r6"): gn_args += mips_arch_variant=\"r6\" @@ -106,20 +106,26 @@ host_build { } else { gn_args += custom_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:target\" gn_args += host_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:host\" + GN_TARGET_CPU = $$gnArch($$QT_ARCH) cross_compile { gn_args += v8_snapshot_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:v8_snapshot\" - GN_TARGET_CPU = $$gnArch($$QT_ARCH) + # FIXME: we should set host_cpu in case host-toolchain doesn't match os arch, + # but currently we don't it available at this point gn_args += target_cpu=\"$$GN_TARGET_CPU\" + } else { + gn_args += host_cpu=\"$$GN_TARGET_CPU\" } !contains(QT_CONFIG, no-pkg-config) { # Strip '>2 /dev/null' from $$pkgConfigExecutable() PKGCONFIG = $$first($$list($$pkgConfigExecutable())) gn_args += pkg_config=\"$$PKGCONFIG\" + gn_args += "host_pkg_config=\"pkg-config\"" } qtConfig(system-zlib): use?(system_minizip): gn_args += use_system_zlib=true use_system_minizip=true - qtConfig(system-png): gn_args += use_system_libpng=true + use?(system_libpng): gn_args += use_system_libpng=true qtConfig(system-jpeg): gn_args += use_system_libjpeg=true + qtConfig(system-freetype): gn_args += use_system_freetype=true use?(system_harfbuzz): gn_args += use_system_harfbuzz=true !use?(glib): gn_args += use_glib=false qtConfig(pulseaudio) { @@ -139,13 +145,13 @@ host_build { use?(system_libevent): gn_args += use_system_libevent=true use?(system_libwebp): gn_args += use_system_libwebp=true - #use?(system_libsrtp): gn_args += use_system_libsrtp=true use?(system_libxslt): gn_args += use_system_libxml=true use_system_libxslt=true #use?(system_jsoncpp): gn_args += use_system_jsoncpp=true use?(system_opus): gn_args += use_system_opus=true use?(system_snappy): gn_args += use_system_snappy=true - use?(system_vpx): gn_args += use_system_libvpx=true + use?(system_libvpx): gn_args += use_system_libvpx=true use?(system_icu): gn_args += use_system_icu=true icu_use_data_file=false use?(system_ffmpeg): gn_args += use_system_ffmpeg=true + use?(system_re2): gn_args += use_system_re2=true #use?(system_protobuf): gn_args += use_system_protobuf=true } diff --git a/src/core/config/windows.pri b/src/core/config/windows.pri index f5dd4a9d3..f74e0bb85 100644 --- a/src/core/config/windows.pri +++ b/src/core/config/windows.pri @@ -7,12 +7,25 @@ gn_args += \ enable_session_service=false \ ninja_use_custom_environment_files=false \ is_multi_dll_chrome=false \ - use_incremental_linking=false \ win_linker_timing=true isDeveloperBuild() { gn_args += \ is_win_fastlink=true + + # Incremental linking doesn't work in release developer builds due to usage of /OPT:ICF + # by Chromium. + CONFIG(debug, debug|release) { + gn_args += \ + use_incremental_linking=true + } else { + gn_args += \ + use_incremental_linking=false + } +} else { + gn_args += \ + is_win_fastlink=false \ + use_incremental_linking=false } defineTest(usingMSVC32BitCrossCompiler) { diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index 42c3f8951..b9e89200d 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -68,7 +68,8 @@ #include "device/geolocation/geolocation_provider.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding_set.h" -#include "services/service_manager/public/cpp/interface_registry.h" +#include "services/service_manager/public/cpp/bind_source_info.h" +#include "services/service_manager/public/cpp/binder_registry.h" #include "third_party/WebKit/public/platform/modules/sensitive_input_visibility/sensitive_input_visibility_service.mojom.h" #include "ui/base/ui_base_switches.h" #include "ui/display/screen.h" @@ -479,6 +480,7 @@ void ContentBrowserClientQt::AllowCertificateError(content::WebContents *webCont void ContentBrowserClientQt::SelectClientCertificate(content::WebContents * /*webContents*/, net::SSLCertRequestInfo * /*certRequestInfo*/, + net::CertificateList /*client_certs*/, std::unique_ptr<content::ClientCertificateDelegate> delegate) { delegate->ContinueWithCertificate(nullptr); @@ -559,6 +561,7 @@ public: return FromWebContents(web_contents); } static void BindSensitiveInputVisibilityService(content::RenderFrameHost* render_frame_host, + const service_manager::BindSourceInfo& source_info, blink::mojom::SensitiveInputVisibilityServiceRequest request) { CreateForRenderFrameHost(render_frame_host); @@ -585,12 +588,54 @@ private: }; -void ContentBrowserClientQt::RegisterRenderFrameMojoInterfaces(service_manager::InterfaceRegistry* registry, - content::RenderFrameHost* render_frame_host) +void ContentBrowserClientQt::ExposeInterfacesToFrame(service_manager::BinderRegistry* registry, + content::RenderFrameHost* render_frame_host) { registry->AddInterface(base::Bind(&ServiceDriver::BindSensitiveInputVisibilityService, render_frame_host)); } +bool ContentBrowserClientQt::CanCreateWindow( + content::RenderFrameHost* opener, + const GURL& opener_url, + const GURL& opener_top_level_frame_url, + const GURL& source_origin, + content::mojom::WindowContainerType container_type, + const GURL& target_url, + const content::Referrer& referrer, + const std::string& frame_name, + WindowOpenDisposition disposition, + const blink::mojom::WindowFeatures& features, + bool user_gesture, + bool opener_suppressed, + bool* no_javascript_access) { + + Q_UNUSED(opener_url); + Q_UNUSED(opener_top_level_frame_url); + Q_UNUSED(source_origin); + Q_UNUSED(container_type); + Q_UNUSED(target_url); + Q_UNUSED(referrer); + Q_UNUSED(frame_name); + Q_UNUSED(disposition); + Q_UNUSED(features); + Q_UNUSED(opener_suppressed); + + if (no_javascript_access) + *no_javascript_access = false; + + content::WebContents* webContents = content::WebContents::FromRenderFrameHost(opener); + + WebEngineSettings *settings = nullptr; + if (webContents) { + WebContentsDelegateQt* delegate = + static_cast<WebContentsDelegateQt*>(webContents->GetDelegate()); + if (delegate) + settings = delegate->webEngineSettings(); + } + + return (settings && settings->getJavaScriptCanOpenWindowsAutomatically()) || user_gesture; +} + } // namespace QtWebEngineCore DEFINE_WEB_CONTENTS_USER_DATA_KEY(QtWebEngineCore::ServiceDriver); diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h index 95c7d2894..eab8e42ab 100644 --- a/src/core/content_browser_client_qt.h +++ b/src/core/content_browser_client_qt.h @@ -66,6 +66,7 @@ class ResourceContext; class WebContentsViewPort; class WebContents; struct MainFunctionParams; +struct Referrer; } namespace gl { @@ -73,7 +74,7 @@ class GLShareGroup; } namespace service_manager { -class InterfaceRegistry; +class BinderRegistry; } namespace QtWebEngineCore { @@ -109,6 +110,7 @@ public: const base::Callback<void(content::CertificateRequestResultType)>& callback) override; void SelectClientCertificate(content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, + net::CertificateList client_certs, std::unique_ptr<content::ClientCertificateDelegate> delegate) override; content::DevToolsManagerDelegate *GetDevToolsManagerDelegate() override; @@ -117,7 +119,22 @@ public: void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) override; void GetAdditionalWebUISchemes(std::vector<std::string>* additional_schemes) override; - void RegisterRenderFrameMojoInterfaces(service_manager::InterfaceRegistry* registry, content::RenderFrameHost* render_frame_host) override; + void ExposeInterfacesToFrame(service_manager::BinderRegistry* registry, content::RenderFrameHost* render_frame_host) override; + + bool CanCreateWindow( + content::RenderFrameHost* opener, + const GURL& opener_url, + const GURL& opener_top_level_frame_url, + const GURL& source_origin, + content::mojom::WindowContainerType container_type, + const GURL& target_url, + const content::Referrer& referrer, + const std::string& frame_name, + WindowOpenDisposition disposition, + const blink::mojom::WindowFeatures& features, + bool user_gesture, + bool opener_suppressed, + bool* no_javascript_access) override; #if defined(Q_OS_LINUX) void GetAdditionalMappedFilesForChildProcess(const base::CommandLine& command_line, int child_process_id, content::FileDescriptorInfo* mappings) override; diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri index 7b55394a4..e013d0703 100644 --- a/src/core/core_chromium.pri +++ b/src/core/core_chromium.pri @@ -98,6 +98,7 @@ SOURCES = \ url_request_context_getter_qt.cpp \ url_request_custom_job.cpp \ url_request_custom_job_delegate.cpp \ + url_request_custom_job_proxy.cpp \ url_request_qrc_job_qt.cpp \ user_script.cpp \ visited_links_manager_qt.cpp \ @@ -176,6 +177,7 @@ HEADERS = \ url_request_context_getter_qt.h \ url_request_custom_job.h \ url_request_custom_job_delegate.h \ + url_request_custom_job_proxy.h \ url_request_qrc_job_qt.h \ user_script.h \ visited_links_manager_qt.h \ diff --git a/src/core/core_module.pro b/src/core/core_module.pro index 3785ddc46..1a5b66867 100644 --- a/src/core/core_module.pro +++ b/src/core/core_module.pro @@ -47,7 +47,17 @@ CONFIG *= no_smart_library_merge osx { LIBS_PRIVATE += -Wl,-force_load,$${api_library_path}$${QMAKE_DIR_SEP}lib$${api_library_name}.a } else:msvc { - QMAKE_LFLAGS += /OPT:REF + !isDeveloperBuild() { + # Remove unused functions and data in debug non-developer builds, because the binaries will + # be smaller in the shipped packages. + QMAKE_LFLAGS += /OPT:REF + } else:CONFIG(debug, debug|release) { + # Make sure to override qtbase's QMAKE_LFLAGS_DEBUG option in debug developer builds, + # because qmake chooses and overrides the option when it gets appended to QMAKE_LFLAGS in + # qtbase\mkspecs\features\default_post.prf, regardless of what Chromium passes back from GN. + QMAKE_LFLAGS_DEBUG -= /DEBUG + QMAKE_LFLAGS_DEBUG += /DEBUG:FASTLINK + } QMAKE_LFLAGS += /WHOLEARCHIVE:$${api_library_path}$${QMAKE_DIR_SEP}$${api_library_name}.lib } else { LIBS_PRIVATE += -Wl,-whole-archive -l$$api_library_name -Wl,-no-whole-archive diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp index 5d6353740..dba25d679 100644 --- a/src/core/delegated_frame_node.cpp +++ b/src/core/delegated_frame_node.cpp @@ -69,7 +69,7 @@ #include "cc/quads/yuv_video_draw_quad.h" #include "cc/resources/returned_resource.h" #include "cc/resources/transferable_resource.h" -#include "content/common/host_shared_bitmap_manager.h" +#include "components/viz/display_compositor/host_shared_bitmap_manager.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_fence.h" @@ -236,8 +236,11 @@ public: QSGNode *) override { QSGTextureNode *textureNode = static_cast<QSGTextureNode*>(*m_nodeIterator++); - if (textureNode->texture() != texture) + if (textureNode->texture() != texture) { textureNode->setTexture(texture); + // @TODO: This is a workaround for funky rendering, figure out why this is needed. + textureNode->markDirty(QSGTextureNode::DirtyGeometry); + } if (textureNode->textureCoordinatesTransform() != texCoordTransForm) textureNode->setTextureCoordinatesTransform(texCoordTransForm); if (textureNode->rect() != rect) @@ -251,15 +254,17 @@ public: QSGTexture::Filtering filtering, QSGNode *) override { QSGTextureNode *textureNode = static_cast<QSGTextureNode*>(*m_nodeIterator++); - + if (textureNode->texture() != texture) { + textureNode->setTexture(texture); + // @TODO: This is a workaround for funky rendering, figure out why this is needed. + textureNode->markDirty(QSGTextureNode::DirtyGeometry); + } if (textureNode->rect() != rect) textureNode->setRect(rect); if (textureNode->sourceRect() != sourceRect) textureNode->setSourceRect(sourceRect); if (textureNode->filtering() != filtering) textureNode->setFiltering(filtering); - if (textureNode->texture() != texture) - textureNode->setTexture(texture); } void setupSolidColorNode(const QRect &rect, const QColor &color, QSGNode *) override { @@ -652,7 +657,7 @@ QSharedPointer<QSGTexture> ResourceHolder::initTexture(bool quadNeedsBlending, R if (!texture) { if (m_resource.is_software) { Q_ASSERT(apiDelegate); - std::unique_ptr<cc::SharedBitmap> sharedBitmap = content::HostSharedBitmapManager::current()->GetSharedBitmapFromId(m_resource.size, m_resource.mailbox_holder.mailbox); + std::unique_ptr<cc::SharedBitmap> sharedBitmap = viz::HostSharedBitmapManager::current()->GetSharedBitmapFromId(m_resource.size, m_resource.mailbox_holder.mailbox); // QSG interprets QImage::hasAlphaChannel meaning that a node should enable blending // to draw it but Chromium keeps this information in the quads. // The input format is currently always Format_ARGB32_Premultiplied, so assume that all @@ -923,6 +928,7 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, rpLayer->setRect(toQt(pass->output_rect)); rpLayer->setSize(toQt(pass->output_rect.size())); rpLayer->setFormat(pass->has_transparent_background ? GL_RGBA : GL_RGB); + rpLayer->setMirrorVertical(true); } else renderPassParent = this; diff --git a/src/core/desktop_screen_qt.cpp b/src/core/desktop_screen_qt.cpp index ec7b6ce98..b63511c92 100644 --- a/src/core/desktop_screen_qt.cpp +++ b/src/core/desktop_screen_qt.cpp @@ -77,11 +77,11 @@ std::vector<display::Display>& DesktopScreenQt::GetAllDisplays() const return empty; } -display::Display DesktopScreenQt::GetDisplayNearestWindow(gfx::NativeView window) const +display::Display DesktopScreenQt::GetDisplayNearestWindow(gfx::NativeWindow window) const { // RenderViewHostImpl::OnStartDragging uses this to determine // the scale factor for the view. - return display::Display(); + return display::Display(0); } display::Display DesktopScreenQt::GetDisplayNearestPoint(const gfx::Point& point) const @@ -98,7 +98,7 @@ display::Display DesktopScreenQt::GetDisplayMatching(const gfx::Rect& match_rect display::Display DesktopScreenQt::GetPrimaryDisplay() const { - return display::Display(); + return display::Display(0); } void DesktopScreenQt::AddObserver(display::DisplayObserver* observer) diff --git a/src/core/desktop_screen_qt.h b/src/core/desktop_screen_qt.h index b91cb6aab..0c52c615a 100644 --- a/src/core/desktop_screen_qt.h +++ b/src/core/desktop_screen_qt.h @@ -52,7 +52,7 @@ public: gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override; int GetNumDisplays() const override; std::vector<display::Display>& GetAllDisplays() const override; - display::Display GetDisplayNearestWindow(gfx::NativeView window) const override; + display::Display GetDisplayNearestWindow(gfx::NativeWindow window) const override; display::Display GetDisplayNearestPoint(const gfx::Point& point) const override; display::Display GetDisplayMatching(const gfx::Rect& match_rect) const override; display::Display GetPrimaryDisplay() const override; diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp index 67c809032..5eb97c5ea 100644 --- a/src/core/download_manager_delegate_qt.cpp +++ b/src/core/download_manager_delegate_qt.cpp @@ -81,7 +81,7 @@ void DownloadManagerDelegateQt::GetNextId(const content::DownloadIdCallback& cal void DownloadManagerDelegateQt::cancelDownload(const content::DownloadTargetCallback& callback) { - callback.Run(base::FilePath(), content::DownloadItem::TARGET_DISPOSITION_PROMPT, content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, base::FilePath()); + callback.Run(base::FilePath(), content::DownloadItem::TARGET_DISPOSITION_PROMPT, content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, base::FilePath(), content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); } void DownloadManagerDelegateQt::cancelDownload(quint32 downloadId) @@ -116,7 +116,7 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* i // store downloads and other special downloads, so they might never end up here anyway. if (!item->GetForcedFilePath().empty()) { callback.Run(item->GetForcedFilePath(), content::DownloadItem::TARGET_DISPOSITION_PROMPT, - content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, item->GetForcedFilePath()); + content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, item->GetForcedFilePath(), content::DOWNLOAD_INTERRUPT_REASON_NONE); return true; } @@ -196,8 +196,11 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* i } base::FilePath filePathForCallback(toFilePathString(suggestedFile.absoluteFilePath())); - callback.Run(filePathForCallback, content::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, filePathForCallback.AddExtension(toFilePathString("download"))); + callback.Run(filePathForCallback, + content::DownloadItem::TARGET_DISPOSITION_OVERWRITE, + content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, + filePathForCallback.AddExtension(toFilePathString("download")), + content::DOWNLOAD_INTERRUPT_REASON_NONE); } else cancelDownload(callback); diff --git a/src/core/gl_surface_qt.cpp b/src/core/gl_surface_qt.cpp index e0672f14f..93c1c5293 100644 --- a/src/core/gl_surface_qt.cpp +++ b/src/core/gl_surface_qt.cpp @@ -48,6 +48,7 @@ #include <QGuiApplication> #include "gl_context_qt.h" #include "qtwebenginecoreglobal_p.h" +#include "web_engine_context.h" #include "base/logging.h" #include "gpu/ipc/service/image_transport_surface.h" @@ -179,6 +180,16 @@ bool GLSurfaceGLX::IsCreateContextRobustnessSupported() return false; // ExtensionsContain(g_extensions, "GLX_ARB_create_context_robustness"); } +bool GLSurfaceGLX::IsEXTSwapControlSupported() +{ + return HasGLXExtension("GLX_EXT_swap_control"); +} + +bool GLSurfaceGLX::IsMESASwapControlSupported() +{ + return HasGLXExtension("GLX_MESA_swap_control"); +} + bool GLSurfaceGLX::IsCreateContextProfileSupported() { return false; // ExtensionsContain(g_extensions, "GLX_ARB_create_context_profile"); @@ -427,6 +438,11 @@ bool GLSurfaceEGL::IsCreateContextWebGLCompatabilitySupported() return false; } +bool GLSurfaceEGL::IsEGLContextPrioritySupported() +{ + return false; +} + void GLSurfaceEGL::ShutdownOneOff() { } @@ -637,6 +653,11 @@ bool InitializeGLOneOffPlatform() return false; } +bool usingSoftwareDynamicGL() +{ + return QtWebEngineCore::usingSoftwareDynamicGL(); +} + scoped_refptr<GLSurface> CreateOffscreenGLSurfaceWithFormat(const gfx::Size& size, GLSurfaceFormat format) { diff --git a/src/core/network_delegate_qt.cpp b/src/core/network_delegate_qt.cpp index 5878095e6..6507ac1cc 100644 --- a/src/core/network_delegate_qt.cpp +++ b/src/core/network_delegate_qt.cpp @@ -316,4 +316,24 @@ bool NetworkDelegateQt::OnCancelURLRequestWithPolicyViolatingReferrerHeader(cons return false; } +bool NetworkDelegateQt::OnCanQueueReportingReport(const url::Origin& origin) const +{ + return false; +} + +bool NetworkDelegateQt::OnCanSendReportingReport(const url::Origin& origin) const +{ + return false; +} + +bool NetworkDelegateQt::OnCanSetReportingClient(const url::Origin& origin, const GURL& endpoint) const +{ + return false; +} + +bool NetworkDelegateQt::OnCanUseReportingClient(const url::Origin& origin, const GURL& endpoint) const +{ + return false; +} + } // namespace QtWebEngineCore diff --git a/src/core/network_delegate_qt.h b/src/core/network_delegate_qt.h index da5b36d19..590b3b20c 100644 --- a/src/core/network_delegate_qt.h +++ b/src/core/network_delegate_qt.h @@ -93,6 +93,13 @@ public: virtual bool OnCanEnablePrivacyMode(const GURL&, const GURL&) const override; virtual bool OnAreExperimentalCookieFeaturesEnabled() const override; virtual bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(const net::URLRequest&, const GURL&, const GURL&) const override; + + virtual bool OnCanQueueReportingReport(const url::Origin& origin) const override; + virtual bool OnCanSendReportingReport(const url::Origin& origin) const override; + virtual bool OnCanSetReportingClient(const url::Origin& origin, + const GURL& endpoint) const override; + virtual bool OnCanUseReportingClient(const url::Origin& origin, + const GURL& endpoint) const override; }; } // namespace QtWebEngineCore diff --git a/src/core/ozone_platform_qt.cpp b/src/core/ozone_platform_qt.cpp index 20c1f43c8..e165239bd 100644 --- a/src/core/ozone_platform_qt.cpp +++ b/src/core/ozone_platform_qt.cpp @@ -99,6 +99,7 @@ public: // PlatformEventDispatcher: bool CanDispatchEvent(const PlatformEvent& event) override; uint32_t DispatchEvent(const PlatformEvent& event) override; + void PrepareForShutdown() override; private: PlatformWindowDelegate* delegate_; @@ -134,6 +135,11 @@ uint32_t PlatformWindowQt::DispatchEvent(const ui::PlatformEvent& native_event) return ui::POST_DISPATCH_STOP_PROPAGATION; } +void PlatformWindowQt::PrepareForShutdown() +{ +} + + class OzonePlatformQt : public OzonePlatform { public: OzonePlatformQt(); @@ -149,8 +155,8 @@ public: ui::OverlayManagerOzone* GetOverlayManager() override; private: - void InitializeUI() override; - void InitializeGPU() override; + void InitializeUI(const ui::OzonePlatform::InitParams &) override; + void InitializeGPU(const ui::OzonePlatform::InitParams &) override; std::unique_ptr<QtWebEngineCore::SurfaceFactoryQt> surface_factory_ozone_; std::unique_ptr<CursorFactoryOzone> cursor_factory_ozone_; @@ -208,7 +214,7 @@ std::unique_ptr<display::NativeDisplayDelegate> OzonePlatformQt::CreateNativeDis return nullptr; } -void OzonePlatformQt::InitializeUI() +void OzonePlatformQt::InitializeUI(const ui::OzonePlatform::InitParams &) { overlay_manager_.reset(new StubOverlayManager()); cursor_factory_ozone_.reset(new CursorFactoryOzone()); @@ -216,7 +222,7 @@ void OzonePlatformQt::InitializeUI() input_controller_ = CreateStubInputController(); } -void OzonePlatformQt::InitializeGPU() +void OzonePlatformQt::InitializeGPU(const ui::OzonePlatform::InitParams &) { surface_factory_ozone_.reset(new QtWebEngineCore::SurfaceFactoryQt()); } @@ -226,7 +232,7 @@ void OzonePlatformQt::InitializeGPU() OzonePlatform* CreateOzonePlatformQt() { return new OzonePlatformQt; } -ClientNativePixmapFactory* CreateClientNativePixmapFactoryQt() +gfx::ClientNativePixmapFactory* CreateClientNativePixmapFactoryQt() { return CreateStubClientNativePixmapFactory(); } diff --git a/src/core/print_view_manager_qt.cpp b/src/core/print_view_manager_qt.cpp index 6493bb7d5..b35f5df4d 100644 --- a/src/core/print_view_manager_qt.cpp +++ b/src/core/print_view_manager_qt.cpp @@ -57,6 +57,7 @@ #include "content/public/common/web_preferences.h" #include "printing/pdf_metafile_skia.h" #include "printing/print_job_constants.h" +#include "printing/units.h" DEFINE_WEB_CONTENTS_USER_DATA_KEY(QtWebEngineCore::PrintViewManagerQt); @@ -129,6 +130,10 @@ static base::DictionaryValue *createPrintSettings() printSettings->SetBoolean(printing::kSettingGenerateDraftData, false); printSettings->SetBoolean(printing::kSettingPreviewModifiable, false); + + printSettings->SetInteger(printing::kSettingDpiHorizontal, printing::kPointsPerInch); + printSettings->SetInteger(printing::kSettingDpiVertical, printing::kPointsPerInch); + printSettings->SetInteger(printing::kSettingDuplexMode, printing::SIMPLEX); printSettings->SetInteger(printing::kSettingCopies, 1); printSettings->SetBoolean(printing::kSettingCollate, false); diff --git a/src/core/qtwebengine_sources.gni b/src/core/qtwebengine_sources.gni index 785c252cb..d7fe4d70d 100644 --- a/src/core/qtwebengine_sources.gni +++ b/src/core/qtwebengine_sources.gni @@ -21,6 +21,7 @@ source_set("qtwebengine_spellcheck_sources") { deps = [ "//components/spellcheck/browser", "//components/spellcheck/renderer", + "//third_party/boringssl", "//third_party/WebKit/public:blink", "//third_party/hunspell", ] @@ -46,8 +47,8 @@ source_set("qtwebengine_sources") { "//chrome/browser/media/webrtc/desktop_streams_registry.h", "//chrome/common/chrome_switches.cc", "//chrome/common/chrome_switches.h", - "//components/prefs/testing_pref_store.cc", - "//components/prefs/testing_pref_store.h", + "//components/prefs/in_memory_pref_store.cc", + "//components/prefs/in_memory_pref_store.h", "//extensions/common/constants.cc", "//extensions/common/constants.h", "//extensions/common/url_pattern.cc", diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 0c98c9e21..f36de68c7 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -73,6 +73,7 @@ #include "ui/gfx/geometry/size_conversions.h" #if defined(USE_AURA) +#include "ui/base/cursor/cursor.h" #include "ui/base/cursor/cursors_aura.h" #endif @@ -80,6 +81,7 @@ #include <QFocusEvent> #include <QGuiApplication> #include <QInputMethodEvent> +#include <QLoggingCategory> #include <QTextFormat> #include <QKeyEvent> #include <QMouseEvent> @@ -104,9 +106,9 @@ enum ImStateFlags { static inline ui::LatencyInfo CreateLatencyInfo(const blink::WebInputEvent& event) { ui::LatencyInfo latency_info; // The latency number should only be added if the timestamp is valid. - if (event.timeStampSeconds()) { + if (event.TimeStampSeconds()) { const int64_t time_micros = static_cast<int64_t>( - event.timeStampSeconds() * base::Time::kMicrosecondsPerSecond); + event.TimeStampSeconds() * base::Time::kMicrosecondsPerSecond); latency_info.AddLatencyNumberWithTimestamp( ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, @@ -217,7 +219,8 @@ public: } int GetFlags() const override { return flags; } float GetPressure(size_t pointer_index) const override { return touchPoints.at(pointer_index).pressure(); } - float GetTilt(size_t pointer_index) const override { return 0; } + float GetTiltX(size_t pointer_index) const override { return 0; } + float GetTiltY(size_t pointer_index) const override { return 0; } base::TimeTicks GetEventTime() const override { return eventTime; } size_t GetHistorySize() const override { return 0; } @@ -260,12 +263,15 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget , m_needsDelegatedFrameAck(false) , m_loadVisuallyCommittedState(NotCommitted) , m_adapterClient(0) + , m_rendererCompositorFrameSink(0) , m_imeInProgress(false) , m_receivedEmptyImeText(false) , m_initPending(false) , m_beginFrameSource(nullptr) , m_needsBeginFrames(false) + , m_needsFlushInput(false) , m_addedFrameObserver(false) + , m_backgroundColor(SK_ColorWHITE) , m_imState(0) , m_anchorPositionWithinSelection(-1) , m_cursorPositionWithinSelection(-1) @@ -443,12 +449,20 @@ gfx::Rect RenderWidgetHostViewQt::GetViewBounds() const return gfx::BoundingRect(p1, p2); } +SkColor RenderWidgetHostViewQt::background_color() const +{ + return m_backgroundColor; +} + void RenderWidgetHostViewQt::SetBackgroundColor(SkColor color) { - RenderWidgetHostViewBase::SetBackgroundColor(color); + if (m_backgroundColor == color) + return; + m_backgroundColor = color; // Set the background of the compositor if necessary m_delegate->setClearColor(toQt(color)); // Set the background of the blink::FrameView + m_host->SetBackgroundOpaque(SkColorGetA(color) == SK_AlphaOPAQUE); m_host->Send(new RenderViewObserverQt_SetBackgroundColor(m_host->GetRoutingID(), color)); } @@ -472,119 +486,119 @@ void RenderWidgetHostViewQt::UnlockMouse() void RenderWidgetHostViewQt::UpdateCursor(const content::WebCursor &webCursor) { - content::WebCursor::CursorInfo cursorInfo; + content::CursorInfo cursorInfo; webCursor.GetCursorInfo(&cursorInfo); Qt::CursorShape shape = Qt::ArrowCursor; #if defined(USE_AURA) - int auraType = -1; + ui::CursorType auraType = ui::CursorType::kNull; #endif switch (cursorInfo.type) { - case blink::WebCursorInfo::TypePointer: + case blink::WebCursorInfo::kTypePointer: shape = Qt::ArrowCursor; break; - case blink::WebCursorInfo::TypeCross: + case blink::WebCursorInfo::kTypeCross: shape = Qt::CrossCursor; break; - case blink::WebCursorInfo::TypeHand: + case blink::WebCursorInfo::kTypeHand: shape = Qt::PointingHandCursor; break; - case blink::WebCursorInfo::TypeIBeam: + case blink::WebCursorInfo::kTypeIBeam: shape = Qt::IBeamCursor; break; - case blink::WebCursorInfo::TypeWait: + case blink::WebCursorInfo::kTypeWait: shape = Qt::WaitCursor; break; - case blink::WebCursorInfo::TypeHelp: + case blink::WebCursorInfo::kTypeHelp: shape = Qt::WhatsThisCursor; break; - case blink::WebCursorInfo::TypeEastResize: - case blink::WebCursorInfo::TypeWestResize: - case blink::WebCursorInfo::TypeEastWestResize: - case blink::WebCursorInfo::TypeEastPanning: - case blink::WebCursorInfo::TypeWestPanning: + case blink::WebCursorInfo::kTypeEastResize: + case blink::WebCursorInfo::kTypeWestResize: + case blink::WebCursorInfo::kTypeEastWestResize: + case blink::WebCursorInfo::kTypeEastPanning: + case blink::WebCursorInfo::kTypeWestPanning: shape = Qt::SizeHorCursor; break; - case blink::WebCursorInfo::TypeNorthResize: - case blink::WebCursorInfo::TypeSouthResize: - case blink::WebCursorInfo::TypeNorthSouthResize: - case blink::WebCursorInfo::TypeNorthPanning: - case blink::WebCursorInfo::TypeSouthPanning: + case blink::WebCursorInfo::kTypeNorthResize: + case blink::WebCursorInfo::kTypeSouthResize: + case blink::WebCursorInfo::kTypeNorthSouthResize: + case blink::WebCursorInfo::kTypeNorthPanning: + case blink::WebCursorInfo::kTypeSouthPanning: shape = Qt::SizeVerCursor; break; - case blink::WebCursorInfo::TypeNorthEastResize: - case blink::WebCursorInfo::TypeSouthWestResize: - case blink::WebCursorInfo::TypeNorthEastSouthWestResize: - case blink::WebCursorInfo::TypeNorthEastPanning: - case blink::WebCursorInfo::TypeSouthWestPanning: + case blink::WebCursorInfo::kTypeNorthEastResize: + case blink::WebCursorInfo::kTypeSouthWestResize: + case blink::WebCursorInfo::kTypeNorthEastSouthWestResize: + case blink::WebCursorInfo::kTypeNorthEastPanning: + case blink::WebCursorInfo::kTypeSouthWestPanning: shape = Qt::SizeBDiagCursor; break; - case blink::WebCursorInfo::TypeNorthWestResize: - case blink::WebCursorInfo::TypeSouthEastResize: - case blink::WebCursorInfo::TypeNorthWestSouthEastResize: - case blink::WebCursorInfo::TypeNorthWestPanning: - case blink::WebCursorInfo::TypeSouthEastPanning: + case blink::WebCursorInfo::kTypeNorthWestResize: + case blink::WebCursorInfo::kTypeSouthEastResize: + case blink::WebCursorInfo::kTypeNorthWestSouthEastResize: + case blink::WebCursorInfo::kTypeNorthWestPanning: + case blink::WebCursorInfo::kTypeSouthEastPanning: shape = Qt::SizeFDiagCursor; break; - case blink::WebCursorInfo::TypeColumnResize: + case blink::WebCursorInfo::kTypeColumnResize: shape = Qt::SplitHCursor; break; - case blink::WebCursorInfo::TypeRowResize: + case blink::WebCursorInfo::kTypeRowResize: shape = Qt::SplitVCursor; break; - case blink::WebCursorInfo::TypeMiddlePanning: - case blink::WebCursorInfo::TypeMove: + case blink::WebCursorInfo::kTypeMiddlePanning: + case blink::WebCursorInfo::kTypeMove: shape = Qt::SizeAllCursor; break; - case blink::WebCursorInfo::TypeProgress: + case blink::WebCursorInfo::kTypeProgress: shape = Qt::BusyCursor; break; #if defined(USE_AURA) - case blink::WebCursorInfo::TypeVerticalText: - auraType = ui::kCursorVerticalText; + case blink::WebCursorInfo::kTypeVerticalText: + auraType = ui::CursorType::kVerticalText; break; - case blink::WebCursorInfo::TypeCell: - auraType = ui::kCursorCell; + case blink::WebCursorInfo::kTypeCell: + auraType = ui::CursorType::kCell; break; - case blink::WebCursorInfo::TypeContextMenu: - auraType = ui::kCursorContextMenu; + case blink::WebCursorInfo::kTypeContextMenu: + auraType = ui::CursorType::kContextMenu; break; - case blink::WebCursorInfo::TypeAlias: - auraType = ui::kCursorAlias; + case blink::WebCursorInfo::kTypeAlias: + auraType = ui::CursorType::kAlias; break; - case blink::WebCursorInfo::TypeCopy: - auraType = ui::kCursorCopy; + case blink::WebCursorInfo::kTypeCopy: + auraType = ui::CursorType::kCopy; break; - case blink::WebCursorInfo::TypeZoomIn: - auraType = ui::kCursorZoomIn; + case blink::WebCursorInfo::kTypeZoomIn: + auraType = ui::CursorType::kZoomIn; break; - case blink::WebCursorInfo::TypeZoomOut: - auraType = ui::kCursorZoomOut; + case blink::WebCursorInfo::kTypeZoomOut: + auraType = ui::CursorType::kZoomOut; break; #else - case blink::WebCursorInfo::TypeVerticalText: - case blink::WebCursorInfo::TypeCell: - case blink::WebCursorInfo::TypeContextMenu: - case blink::WebCursorInfo::TypeAlias: - case blink::WebCursorInfo::TypeCopy: - case blink::WebCursorInfo::TypeZoomIn: - case blink::WebCursorInfo::TypeZoomOut: + case blink::WebCursorInfo::kTypeVerticalText: + case blink::WebCursorInfo::kTypeCell: + case blink::WebCursorInfo::kTypeContextMenu: + case blink::WebCursorInfo::kTypeAlias: + case blink::WebCursorInfo::kTypeCopy: + case blink::WebCursorInfo::kTypeZoomIn: + case blink::WebCursorInfo::kTypeZoomOut: // FIXME: Support on OS X break; #endif - case blink::WebCursorInfo::TypeNoDrop: - case blink::WebCursorInfo::TypeNotAllowed: + case blink::WebCursorInfo::kTypeNoDrop: + case blink::WebCursorInfo::kTypeNotAllowed: shape = Qt::ForbiddenCursor; break; - case blink::WebCursorInfo::TypeNone: + case blink::WebCursorInfo::kTypeNone: shape = Qt::BlankCursor; break; - case blink::WebCursorInfo::TypeGrab: + case blink::WebCursorInfo::kTypeGrab: shape = Qt::OpenHandCursor; break; - case blink::WebCursorInfo::TypeGrabbing: + case blink::WebCursorInfo::kTypeGrabbing: shape = Qt::ClosedHandCursor; break; - case blink::WebCursorInfo::TypeCustom: + case blink::WebCursorInfo::kTypeCustom: if (cursorInfo.custom_image.colorType() == SkColorType::kN32_SkColorType) { QImage cursor = toQImage(cursorInfo.custom_image, QImage::Format_ARGB32); m_delegate->updateCursor(QCursor(QPixmap::fromImage(cursor), cursorInfo.hotspot.x(), cursorInfo.hotspot.y())); @@ -593,7 +607,7 @@ void RenderWidgetHostViewQt::UpdateCursor(const content::WebCursor &webCursor) break; } #if defined(USE_AURA) - if (auraType > 0) { + if (auraType != ui::CursorType::kNull) { SkBitmap bitmap; gfx::Point hotspot; if (ui::GetCursorBitmap(auraType, &bitmap, &hotspot)) { @@ -644,15 +658,28 @@ bool RenderWidgetHostViewQt::HasAcceleratedSurface(const gfx::Size&) return false; } -void RenderWidgetHostViewQt::OnSwapCompositorFrame(uint32_t output_surface_id, cc::CompositorFrame frame) +void RenderWidgetHostViewQt::DidCreateNewRendererCompositorFrameSink(cc::mojom::MojoCompositorFrameSinkClient *frameSink) +{ + // Accumulated resources belong to the old RendererCompositorFrameSink and + // should not be returned. + m_resourcesToRelease.clear(); + m_rendererCompositorFrameSink = frameSink; +} + +void RenderWidgetHostViewQt::SubmitCompositorFrame(const cc::LocalSurfaceId &local_surface_id, cc::CompositorFrame frame) { 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; + m_backgroundColor = frame.metadata.root_background_color; + if (m_localSurfaceId != local_surface_id) { + m_localSurfaceId = local_surface_id; + // FIXME: update frame_size and device_scale_factor? + // FIXME: showPrimarySurface()? + } Q_ASSERT(!m_needsDelegatedFrameAck); m_needsDelegatedFrameAck = true; - m_pendingOutputSurfaceId = output_surface_id; m_chromiumCompositorData->previousFrameData = std::move(m_chromiumCompositorData->frameData); m_chromiumCompositorData->frameDevicePixelRatio = frame.metadata.device_scale_factor; m_chromiumCompositorData->frameData = std::move(frame); @@ -919,11 +946,11 @@ bool RenderWidgetHostViewQt::forwardEvent(QEvent *event) case QEvent::TouchCancel: handleTouchEvent(static_cast<QTouchEvent*>(event)); break; +#ifndef QT_NO_GESTURES case QEvent::NativeGesture: handleGestureEvent(static_cast<QNativeGestureEvent *>(event)); break; - case QEvent::HoverEnter: - case QEvent::HoverLeave: +#endif // QT_NO_GESTURES case QEvent::HoverMove: handleHoverEvent(static_cast<QHoverEvent*>(event)); break; @@ -983,7 +1010,7 @@ QVariant RenderWidgetHostViewQt::inputMethodQuery(Qt::InputMethodQuery query) void RenderWidgetHostViewQt::ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, content::InputEventAckState ack_result) { Q_UNUSED(touch); const bool eventConsumed = ack_result == content::INPUT_EVENT_ACK_STATE_CONSUMED; - m_gestureProvider.OnTouchEventAck(touch.event.uniqueTouchEventId, eventConsumed); + m_gestureProvider.OnTouchEventAck(touch.event.unique_touch_event_id, eventConsumed); } void RenderWidgetHostViewQt::sendDelegatedFrameAck() @@ -992,9 +1019,8 @@ void RenderWidgetHostViewQt::sendDelegatedFrameAck() m_beginFrameSource->DidFinishFrame(this, ack); cc::ReturnedResourceArray resources; m_resourcesToRelease.swap(resources); - content::RenderWidgetHostImpl::SendReclaimCompositorResources( - m_host->GetRoutingID(), m_pendingOutputSurfaceId, - m_host->GetProcess()->GetID(), true, resources); + if (m_rendererCompositorFrameSink) + m_rendererCompositorFrameSink->DidReceiveCompositorFrameAck(resources); } void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEvent) @@ -1034,7 +1060,7 @@ float RenderWidgetHostViewQt::dpiScale() const bool RenderWidgetHostViewQt::IsPopup() const { - return popup_type_ != blink::WebPopupTypeNone; + return popup_type_ != blink::kWebPopupTypeNone; } void RenderWidgetHostViewQt::handleMouseEvent(QMouseEvent* event) @@ -1047,8 +1073,8 @@ void RenderWidgetHostViewQt::handleMouseEvent(QMouseEvent* event) return; blink::WebMouseEvent webEvent = WebEventFactory::toWebMouseEvent(event, dpiScale()); - if ((webEvent.type() == blink::WebInputEvent::MouseDown || webEvent.type() == blink::WebInputEvent::MouseUp) - && webEvent.button == blink::WebMouseEvent::Button::NoButton) { + if ((webEvent.GetType() == blink::WebInputEvent::kMouseDown || webEvent.GetType() == blink::WebInputEvent::kMouseUp) + && webEvent.button == blink::WebMouseEvent::Button::kNoButton) { // Blink can only handle the 3 main mouse-buttons and may assert when processing mouse-down for no button. return; } @@ -1061,13 +1087,13 @@ void RenderWidgetHostViewQt::handleMouseEvent(QMouseEvent* event) m_clickHelper.clickCounter = 0; m_clickHelper.lastPressTimestamp = event->timestamp(); - webEvent.clickCount = ++m_clickHelper.clickCounter; + webEvent.click_count = ++m_clickHelper.clickCounter; m_clickHelper.lastPressButton = event->button(); m_clickHelper.lastPressPosition = QPointF(event->pos()).toPoint(); } - webEvent.movementX = event->globalX() - m_previousMousePosition.x(); - webEvent.movementY = event->globalY() - m_previousMousePosition.y(); + webEvent.movement_x = event->globalX() - m_previousMousePosition.x(); + webEvent.movement_y = event->globalY() - m_previousMousePosition.y(); if (IsMouseLocked()) QCursor::setPos(m_previousMousePosition); @@ -1118,7 +1144,7 @@ void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev) } content::NativeWebKeyboardEvent webEvent = WebEventFactory::toWebKeyboardEvent(ev); - bool keyDownTextInsertion = webEvent.type() == blink::WebInputEvent::RawKeyDown && webEvent.text[0]; + bool keyDownTextInsertion = webEvent.GetType() == blink::WebInputEvent::kRawKeyDown && webEvent.text[0]; webEvent.skip_in_browser = keyDownTextInsertion; m_host->ForwardKeyboardEvent(webEvent); @@ -1127,7 +1153,7 @@ void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev) // The RawKeyDown is skipped on the way back (see above). // The same os_event will be set on both NativeWebKeyboardEvents. webEvent.skip_in_browser = false; - webEvent.setType(blink::WebInputEvent::Char); + webEvent.SetType(blink::WebInputEvent::kChar); m_host->ForwardKeyboardEvent(webEvent); } } @@ -1316,6 +1342,7 @@ void RenderWidgetHostViewQt::clearPreviousTouchMotionState() m_touchMotionStarted = false; } +#ifndef QT_NO_GESTURES void RenderWidgetHostViewQt::handleGestureEvent(QNativeGestureEvent *ev) { const Qt::NativeGestureType type = ev->gestureType(); @@ -1326,12 +1353,22 @@ void RenderWidgetHostViewQt::handleGestureEvent(QNativeGestureEvent *ev) static_cast<double>(dpiScale()))); } } +#endif + +Q_DECLARE_LOGGING_CATEGORY(QWEBENGINE_TOUCH_HANDLING); +Q_LOGGING_CATEGORY(QWEBENGINE_TOUCH_HANDLING, "qt.webengine.touch"); void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev) { // On macOS instead of handling touch events, we use the OS provided QNativeGestureEvents. #ifdef Q_OS_MACOS - return; + if (ev->spontaneous()) { + return; + } else { + qCWarning(QWEBENGINE_TOUCH_HANDLING) + << "Sending simulated touch events to Chromium does not work properly on macOS. " + "Consider using QNativeGestureEvents or QMouseEvents."; + } #endif // Chromium expects the touch event timestamps to be comparable to base::TimeTicks::Now(). @@ -1445,24 +1482,34 @@ void RenderWidgetHostViewQt::SetNeedsBeginFrames(bool needs_begin_frames) updateNeedsBeginFramesInternal(); } +void RenderWidgetHostViewQt::OnSetNeedsFlushInput() +{ + m_needsFlushInput = true; + updateNeedsBeginFramesInternal(); +} + void RenderWidgetHostViewQt::updateNeedsBeginFramesInternal() { if (!m_beginFrameSource) return; - if (m_addedFrameObserver == m_needsBeginFrames) + // Based on upstream Chromium commit 7f7c8cc8b97dd0d5c9159d9e60c62efbc35e6b53. + bool needsFrame = m_needsBeginFrames || m_needsFlushInput; + if (m_addedFrameObserver == needsFrame) return; - if (m_needsBeginFrames) + m_addedFrameObserver = needsFrame; + if (needsFrame) m_beginFrameSource->AddObserver(this); else m_beginFrameSource->RemoveObserver(this); - m_addedFrameObserver = m_needsBeginFrames; } bool RenderWidgetHostViewQt::OnBeginFrameDerivedImpl(const cc::BeginFrameArgs& args) { + m_needsFlushInput = false; m_beginFrameSource->OnUpdateVSyncParameters(args.frame_time, args.interval); + updateNeedsBeginFramesInternal(); m_host->Send(new ViewMsg_BeginFrame(m_host->GetRoutingID(), args)); return true; } diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h index cb1a5980d..63efad87e 100644 --- a/src/core/render_widget_host_view_qt.h +++ b/src/core/render_widget_host_view_qt.h @@ -138,6 +138,7 @@ public: void Hide() override; bool IsShowing() override; gfx::Rect GetViewBounds() const override; + SkColor background_color() const override; void SetBackgroundColor(SkColor color) override; bool LockMouse() override; void UnlockMouse() override; @@ -149,13 +150,15 @@ public: void Destroy() override; void SetTooltipText(const base::string16 &tooltip_text) override; bool HasAcceleratedSurface(const gfx::Size&) override; - void OnSwapCompositorFrame(uint32_t output_surface_id, cc::CompositorFrame frame) override; + void DidCreateNewRendererCompositorFrameSink(cc::mojom::MojoCompositorFrameSinkClient*) override; + void SubmitCompositorFrame(const cc::LocalSurfaceId&, cc::CompositorFrame) override; void GetScreenInfo(content::ScreenInfo* results); gfx::Rect GetBoundsInRootWindow() override; void ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, content::InputEventAckState ack_result) override; void ClearCompositorFrame() override; void SetNeedsBeginFrames(bool needs_begin_frames) override; + void OnSetNeedsFlushInput() override; // Overridden from ui::GestureProviderClient. void OnGestureEvent(const ui::GestureEventData& gesture) override; @@ -183,7 +186,9 @@ public: void handleKeyEvent(QKeyEvent*); void handleWheelEvent(QWheelEvent*); void handleTouchEvent(QTouchEvent*); +#ifndef QT_NO_GESTURES void handleGestureEvent(QNativeGestureEvent *); +#endif void handleHoverEvent(QHoverEvent*); void handleFocusEvent(QFocusEvent*); void handleInputMethodEvent(QInputMethodEvent*); @@ -237,11 +242,11 @@ private: cc::ReturnedResourceArray m_resourcesToRelease; bool m_needsDelegatedFrameAck; LoadVisuallyCommittedState m_loadVisuallyCommittedState; - uint32_t m_pendingOutputSurfaceId; QMetaObject::Connection m_adapterClientDestroyedConnection; WebContentsAdapterClient *m_adapterClient; MultipleMouseClickHelper m_clickHelper; + cc::mojom::MojoCompositorFrameSinkClient *m_rendererCompositorFrameSink; bool m_imeInProgress; bool m_receivedEmptyImeText; @@ -251,10 +256,13 @@ private: std::unique_ptr<cc::SyntheticBeginFrameSource> m_beginFrameSource; bool m_needsBeginFrames; + bool m_needsFlushInput; bool m_addedFrameObserver; gfx::Vector2dF m_lastScrollOffset; gfx::SizeF m_lastContentsSize; + SkColor m_backgroundColor; + cc::LocalSurfaceId m_localSurfaceId; uint m_imState; int m_anchorPositionWithinSelection; diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp index f09aa48f0..ab8e27939 100644 --- a/src/core/renderer/content_renderer_client_qt.cpp +++ b/src/core/renderer/content_renderer_client_qt.cpp @@ -57,6 +57,9 @@ #include "components/visitedlink/renderer/visitedlink_slave.h" #include "components/web_cache/renderer/web_cache_impl.h" #include "content/public/renderer/render_frame.h" +#include "content/public/child/child_thread.h" +#include "content/public/common/service_manager_connection.h" +#include "content/public/common/simple_connection_filter.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_view.h" #include "net/base/net_errors.h" @@ -75,7 +78,7 @@ #include "renderer/render_view_observer_qt.h" #include "renderer/user_resource_controller.h" #include "renderer/web_channel_ipc_transport.h" -#include "services/service_manager/public/cpp/interface_registry.h" +#include "services/service_manager/public/cpp/binder_registry.h" #include "components/grit/components_resources.h" @@ -98,8 +101,16 @@ void ContentRendererClientQt::RenderThreadStarted() content::RenderThread *renderThread = content::RenderThread::Get(); m_visitedLinkSlave.reset(new visitedlink::VisitedLinkSlave); m_webCacheImpl.reset(new web_cache::WebCacheImpl()); - renderThread->GetInterfaceRegistry()->AddInterface( - m_visitedLinkSlave->GetBindCallback()); + + auto registry = base::MakeUnique<service_manager::BinderRegistry>(); + registry->AddInterface(m_visitedLinkSlave->GetBindCallback(), + base::ThreadTaskRunnerHandle::Get()); + content::ChildThread::Get() + ->GetServiceManagerConnection() + ->AddConnectionFilter(base::MakeUnique<content::SimpleConnectionFilter>( + std::move(registry))); + + renderThread->AddObserver(UserResourceController::instance()); #if BUILDFLAG(ENABLE_SPELLCHECK) @@ -114,15 +125,16 @@ void ContentRendererClientQt::RenderViewCreated(content::RenderView* render_view new RenderViewObserverQt(render_view, m_webCacheImpl.data()); new WebChannelIPCTransport(render_view); UserResourceController::instance()->renderViewCreated(render_view); -#if BUILDFLAG(ENABLE_SPELLCHECK) - new SpellCheckProvider(render_view, m_spellCheck.data()); -#endif - } void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame* render_frame) { new QtWebEngineCore::RenderFrameObserverQt(render_frame); + UserResourceController::instance()->renderFrameCreated(render_frame); + +#if BUILDFLAG(ENABLE_SPELLCHECK) + new SpellCheckProvider(render_frame, m_spellCheck.data()); +#endif #if BUILDFLAG(ENABLE_BASIC_PRINTING) new printing::PrintWebViewHelper( render_frame, @@ -173,7 +185,7 @@ bool ContentRendererClientQt::ShouldSuppressErrorPage(content::RenderFrame *fram // To tap into the chromium localized strings. Ripped from the chrome layer (highly simplified). void ContentRendererClientQt::GetNavigationErrorStrings(content::RenderFrame* renderFrame, const blink::WebURLRequest &failedRequest, const blink::WebURLError &error, std::string *errorHtml, base::string16 *errorDescription) { - const bool isPost = QByteArray::fromStdString(failedRequest.httpMethod().utf8()) == QByteArrayLiteral("POST"); + const bool isPost = QByteArray::fromStdString(failedRequest.HttpMethod().Utf8()) == QByteArrayLiteral("POST"); if (errorHtml) { // Use a local error page. @@ -184,8 +196,8 @@ void ContentRendererClientQt::GetNavigationErrorStrings(content::RenderFrame* re // 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.utf8(), error.unreachableURL, isPost - , error.staleCopyInCache && !isPost, false, false, locale + error_page::LocalizedError::GetStrings(error.reason, error.domain.Utf8(), error.unreachable_url, isPost + , error.stale_copy_in_cache && !isPost, false, false, locale , std::unique_ptr<error_page::ErrorPageParams>(), &errorStrings); resourceId = IDR_NET_ERROR_HTML; @@ -198,7 +210,7 @@ void ContentRendererClientQt::GetNavigationErrorStrings(content::RenderFrame* re } if (errorDescription) - *errorDescription = error_page::LocalizedError::GetErrorDetails(error.domain.utf8(), error.reason, isPost); + *errorDescription = error_page::LocalizedError::GetErrorDetails(error.domain.Utf8(), error.reason, isPost); } unsigned long long ContentRendererClientQt::VisitedLinkHash(const char *canonicalUrl, size_t length) diff --git a/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp b/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp index 3a34d5f93..5111a3129 100644 --- a/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp +++ b/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp @@ -138,8 +138,8 @@ enum FlashNavigateUsage { FLASH_NAVIGATE_USAGE_ENUM_COUNT }; -static base::LazyInstance<std::map<std::string, FlashNavigateUsage> > -g_rejected_headers = LAZY_INSTANCE_INITIALIZER; +static base::LazyInstance<std::map<std::string, FlashNavigateUsage>>:: + DestructorAtExit g_rejected_headers = LAZY_INSTANCE_INITIALIZER; bool IsSimpleHeader(const std::string& lower_case_header_name, const std::string& header_value) diff --git a/src/core/renderer/render_frame_observer_qt.cpp b/src/core/renderer/render_frame_observer_qt.cpp index 111323b8a..7e6d11644 100644 --- a/src/core/renderer/render_frame_observer_qt.cpp +++ b/src/core/renderer/render_frame_observer_qt.cpp @@ -64,6 +64,10 @@ RenderFrameObserverQt::~RenderFrameObserverQt() { } +void RenderFrameObserverQt::OnDestruct() { + delete this; +} + #if BUILDFLAG(ENABLE_PLUGINS) void RenderFrameObserverQt::DidCreatePepperPlugin(content::RendererPpapiHost* host) { diff --git a/src/core/renderer/render_frame_observer_qt.h b/src/core/renderer/render_frame_observer_qt.h index 7abd17e96..ac098a961 100644 --- a/src/core/renderer/render_frame_observer_qt.h +++ b/src/core/renderer/render_frame_observer_qt.h @@ -63,7 +63,7 @@ public: #if BUILDFLAG(ENABLE_PLUGINS) void DidCreatePepperPlugin(content::RendererPpapiHost* host) override; #endif - void OnDestruct() override { } + void OnDestruct() override; void FrameDetached() override; bool isFrameDetached() const; diff --git a/src/core/renderer/render_view_observer_qt.cpp b/src/core/renderer/render_view_observer_qt.cpp index 54aed8b59..4893a5188 100644 --- a/src/core/renderer/render_view_observer_qt.cpp +++ b/src/core/renderer/render_view_observer_qt.cpp @@ -62,25 +62,30 @@ RenderViewObserverQt::RenderViewObserverQt( void RenderViewObserverQt::onFetchDocumentMarkup(quint64 requestId) { blink::WebString markup; - if (render_view()->GetWebView()->mainFrame()->isWebLocalFrame()) - markup = blink::WebFrameContentDumper::dumpAsMarkup( - static_cast<blink::WebLocalFrame*>(render_view()->GetWebView()->mainFrame())); - Send(new RenderViewObserverHostQt_DidFetchDocumentMarkup(routing_id(), requestId, markup.utf16())); + if (render_view()->GetWebView()->MainFrame()->IsWebLocalFrame()) + markup = blink::WebFrameContentDumper::DumpAsMarkup( + static_cast<blink::WebLocalFrame*>(render_view()->GetWebView()->MainFrame())); + Send(new RenderViewObserverHostQt_DidFetchDocumentMarkup(routing_id(), requestId, markup.Utf16())); } void RenderViewObserverQt::onFetchDocumentInnerText(quint64 requestId) { blink::WebString text; - if (render_view()->GetWebView()->mainFrame()->isWebLocalFrame()) - text = blink::WebFrameContentDumper::dumpWebViewAsText( + if (render_view()->GetWebView()->MainFrame()->IsWebLocalFrame()) + text = blink::WebFrameContentDumper::DumpWebViewAsText( render_view()->GetWebView(), std::numeric_limits<std::size_t>::max()); - Send(new RenderViewObserverHostQt_DidFetchDocumentInnerText(routing_id(), requestId, text.utf16())); + Send(new RenderViewObserverHostQt_DidFetchDocumentInnerText(routing_id(), requestId, text.Utf16())); } void RenderViewObserverQt::onSetBackgroundColor(quint32 color) { - render_view()->GetWebFrameWidget()->setBaseBackgroundColor(color); + render_view()->GetWebFrameWidget()->SetBaseBackgroundColor(color); +} + +void RenderViewObserverQt::OnDestruct() +{ + delete this; } bool RenderViewObserverQt::OnMessageReceived(const IPC::Message& message) diff --git a/src/core/renderer/render_view_observer_qt.h b/src/core/renderer/render_view_observer_qt.h index 60b11c428..abb472f02 100644 --- a/src/core/renderer/render_view_observer_qt.h +++ b/src/core/renderer/render_view_observer_qt.h @@ -57,7 +57,7 @@ private: void onFetchDocumentInnerText(quint64 requestId); void onSetBackgroundColor(quint32 color); - void OnDestruct() override { } + void OnDestruct() override; bool OnMessageReceived(const IPC::Message& message) override; void Navigate(const GURL& url) override; diff --git a/src/core/renderer/user_resource_controller.cpp b/src/core/renderer/user_resource_controller.cpp index b172c762b..b4375dfdb 100644 --- a/src/core/renderer/user_resource_controller.cpp +++ b/src/core/renderer/user_resource_controller.cpp @@ -39,10 +39,12 @@ #include "user_resource_controller.h" +#include "base/memory/weak_ptr.h" #include "base/pending_task.h" #include "base/strings/pattern.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" +#include "content/public/renderer/render_frame_observer.h" #include "content/public/renderer/render_view_observer.h" #include "extensions/common/url_pattern.h" #include "third_party/WebKit/public/web/WebDocument.h" @@ -97,16 +99,19 @@ static bool scriptMatchesURL(const UserScriptData &scriptData, const GURL &url) return true; } -class UserResourceController::RenderViewObserverHelper : public content::RenderViewObserver +class UserResourceController::RenderFrameObserverHelper : public content::RenderFrameObserver { public: - RenderViewObserverHelper(content::RenderView *); + RenderFrameObserverHelper(content::RenderFrame* render_frame); + private: - // RenderViewObserver implementation. - void DidFinishDocumentLoad(blink::WebLocalFrame* frame) override; - void DidFinishLoad(blink::WebLocalFrame* frame) override; - void DidStartProvisionalLoad(blink::WebLocalFrame* frame) override; - void FrameDetached(blink::WebFrame* frame) override; + ~RenderFrameObserverHelper() override; + + // RenderFrameObserver implementation. + void DidFinishDocumentLoad() override; + void DidFinishLoad() override; + void DidStartProvisionalLoad(blink::WebDataSource* data_source) override; + void FrameDetached() override; void OnDestruct() override; bool OnMessageReceived(const IPC::Message& message) override; @@ -115,10 +120,24 @@ private: void onScriptsCleared(); void runScripts(UserScriptData::InjectionPoint, blink::WebLocalFrame *); + + // Set of frames which are pending to get an AfterLoad invocation of runScripts, if they + // haven't gotten it already. QSet<blink::WebLocalFrame *> m_pendingFrames; + base::WeakPtrFactory<RenderFrameObserverHelper> m_weakPtrFactory; +}; + +// Used only for script cleanup on RenderView destruction. +class UserResourceController::RenderViewObserverHelper : public content::RenderViewObserver +{ +public: + RenderViewObserverHelper(content::RenderView* render_view); +private: + // RenderViewObserver implementation. + void OnDestruct() override; }; -void UserResourceController::RenderViewObserverHelper::runScripts(UserScriptData::InjectionPoint p, blink::WebLocalFrame *frame) +void UserResourceController::RenderFrameObserverHelper::runScripts(UserScriptData::InjectionPoint p, blink::WebLocalFrame *frame) { if (p == UserScriptData::AfterLoad && !m_pendingFrames.remove(frame)) return; @@ -128,10 +147,11 @@ void UserResourceController::RenderViewObserverHelper::runScripts(UserScriptData void UserResourceController::runScripts(UserScriptData::InjectionPoint p, blink::WebLocalFrame *frame) { - content::RenderView *renderView = content::RenderView::FromWebView(frame->view()); - const bool isMainFrame = (frame == renderView->GetWebView()->mainFrame()); + content::RenderFrame *renderFrame = content::RenderFrame::FromWebFrame(frame); + content::RenderView *renderView = renderFrame->GetRenderView(); + const bool isMainFrame = renderFrame->IsMainFrame(); - QList<uint64_t> scriptsToRun = m_viewUserScriptMap.value(globalScriptsIndex).toList(); + QList<uint64_t> scriptsToRun = m_viewUserScriptMap.value(0).toList(); scriptsToRun.append(m_viewUserScriptMap.value(renderView).toList()); Q_FOREACH (uint64_t id, scriptsToRun) { @@ -139,13 +159,13 @@ void UserResourceController::runScripts(UserScriptData::InjectionPoint p, blink: if (script.injectionPoint != p || (!script.injectForSubframes && !isMainFrame)) continue; - if (!scriptMatchesURL(script, frame->document().url())) + if (!scriptMatchesURL(script, frame->GetDocument().Url())) continue; - blink::WebScriptSource source(blink::WebString::fromUTF8(script.source), script.url); + blink::WebScriptSource source(blink::WebString::FromUTF8(script.source), script.url); if (script.worldId) - frame->executeScriptInIsolatedWorld(script.worldId, &source, /*numSources = */1, /*contentScriptExtentsionGroup = */ 0); + frame->ExecuteScriptInIsolatedWorld(script.worldId, &source, /*numSources = */1, /*contentScriptExtentsionGroup = */ 0); else - frame->executeScript(source); + frame->ExecuteScript(source); } } @@ -159,67 +179,92 @@ void UserResourceController::RunScriptsAtDocumentEnd(content::RenderFrame *rende runScripts(UserScriptData::DocumentLoadFinished, render_frame->GetWebFrame()); } -UserResourceController::RenderViewObserverHelper::RenderViewObserverHelper(content::RenderView *renderView) - : content::RenderViewObserver(renderView) +UserResourceController::RenderFrameObserverHelper::RenderFrameObserverHelper(content::RenderFrame *render_frame) + : content::RenderFrameObserver(render_frame), m_weakPtrFactory(this) { } -void UserResourceController::RenderViewObserverHelper::DidFinishDocumentLoad(blink::WebLocalFrame *frame) +UserResourceController::RenderFrameObserverHelper::~RenderFrameObserverHelper() { + m_weakPtrFactory.InvalidateWeakPtrs(); +} + +UserResourceController::RenderViewObserverHelper::RenderViewObserverHelper(content::RenderView *render_view) + : content::RenderViewObserver(render_view) +{ +} + +void UserResourceController::RenderFrameObserverHelper::DidFinishDocumentLoad() +{ + blink::WebLocalFrame *frame = render_frame()->GetWebFrame(); m_pendingFrames.insert(frame); - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, base::Bind(&UserResourceController::RenderViewObserverHelper::runScripts, - base::Unretained(this), UserScriptData::AfterLoad, frame), + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, base::Bind(&UserResourceController::RenderFrameObserverHelper::runScripts, + m_weakPtrFactory.GetWeakPtr(), UserScriptData::AfterLoad, frame), base::TimeDelta::FromMilliseconds(afterLoadTimeout)); } -void UserResourceController::RenderViewObserverHelper::DidFinishLoad(blink::WebLocalFrame *frame) +void UserResourceController::RenderFrameObserverHelper::DidFinishLoad() { + blink::WebLocalFrame *frame = render_frame()->GetWebFrame(); + // DidFinishDocumentLoad always comes before this, so frame has already been marked as pending. - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(&UserResourceController::RenderViewObserverHelper::runScripts, - base::Unretained(this), UserScriptData::AfterLoad, frame)); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(&UserResourceController::RenderFrameObserverHelper::runScripts, + m_weakPtrFactory.GetWeakPtr(), UserScriptData::AfterLoad, frame)); } -void UserResourceController::RenderViewObserverHelper::DidStartProvisionalLoad(blink::WebLocalFrame *frame) +void UserResourceController::RenderFrameObserverHelper::DidStartProvisionalLoad(blink::WebDataSource *data_source) { + Q_UNUSED(data_source); + blink::WebLocalFrame *frame = render_frame()->GetWebFrame(); m_pendingFrames.remove(frame); } -void UserResourceController::RenderViewObserverHelper::FrameDetached(blink::WebFrame *frame) +void UserResourceController::RenderFrameObserverHelper::FrameDetached() { - if (frame->isWebLocalFrame()) - m_pendingFrames.remove(frame->toWebLocalFrame()); + blink::WebLocalFrame *frame = render_frame()->GetWebFrame(); + m_pendingFrames.remove(frame); +} + +void UserResourceController::RenderFrameObserverHelper::OnDestruct() +{ + delete this; } void UserResourceController::RenderViewObserverHelper::OnDestruct() { + // Remove all scripts associated with the render view. UserResourceController::instance()->renderViewDestroyed(render_view()); + delete this; } -bool UserResourceController::RenderViewObserverHelper::OnMessageReceived(const IPC::Message &message) +bool UserResourceController::RenderFrameObserverHelper::OnMessageReceived(const IPC::Message &message) { bool handled = true; - IPC_BEGIN_MESSAGE_MAP(UserResourceController::RenderViewObserverHelper, message) - IPC_MESSAGE_HANDLER(RenderViewObserverHelper_AddScript, onUserScriptAdded) - IPC_MESSAGE_HANDLER(RenderViewObserverHelper_RemoveScript, onUserScriptRemoved) - IPC_MESSAGE_HANDLER(RenderViewObserverHelper_ClearScripts, onScriptsCleared) + IPC_BEGIN_MESSAGE_MAP(UserResourceController::RenderFrameObserverHelper, message) + IPC_MESSAGE_HANDLER(RenderFrameObserverHelper_AddScript, onUserScriptAdded) + IPC_MESSAGE_HANDLER(RenderFrameObserverHelper_RemoveScript, onUserScriptRemoved) + IPC_MESSAGE_HANDLER(RenderFrameObserverHelper_ClearScripts, onScriptsCleared) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; } -void UserResourceController::RenderViewObserverHelper::onUserScriptAdded(const UserScriptData &script) +void UserResourceController::RenderFrameObserverHelper::onUserScriptAdded(const UserScriptData &script) { - UserResourceController::instance()->addScriptForView(script, render_view()); + content::RenderView *view = render_frame()->GetRenderView(); + UserResourceController::instance()->addScriptForView(script, view); } -void UserResourceController::RenderViewObserverHelper::onUserScriptRemoved(const UserScriptData &script) +void UserResourceController::RenderFrameObserverHelper::onUserScriptRemoved(const UserScriptData &script) { - UserResourceController::instance()->removeScriptForView(script, render_view()); + content::RenderView *view = render_frame()->GetRenderView(); + UserResourceController::instance()->removeScriptForView(script, view); } -void UserResourceController::RenderViewObserverHelper::onScriptsCleared() +void UserResourceController::RenderFrameObserverHelper::onScriptsCleared() { - UserResourceController::instance()->clearScriptsForView(render_view()); + content::RenderView *view = render_frame()->GetRenderView(); + UserResourceController::instance()->clearScriptsForView(view); } UserResourceController *UserResourceController::instance() @@ -248,9 +293,15 @@ UserResourceController::UserResourceController() #endif // !defined(QT_NO_DEBUG) || defined(QT_FORCE_ASSERTS) } +void UserResourceController::renderFrameCreated(content::RenderFrame *renderFrame) +{ + // Will destroy itself when the RenderFrame is destroyed. + new RenderFrameObserverHelper(renderFrame); +} + void UserResourceController::renderViewCreated(content::RenderView *renderView) { - // Will destroy itself with their RenderView. + // Will destroy itself when the RenderView is destroyed. new RenderViewObserverHelper(renderView); } diff --git a/src/core/renderer/user_resource_controller.h b/src/core/renderer/user_resource_controller.h index 5d412fe40..50af24243 100644 --- a/src/core/renderer/user_resource_controller.h +++ b/src/core/renderer/user_resource_controller.h @@ -61,8 +61,9 @@ class UserResourceController : public content::RenderThreadObserver { public: static UserResourceController *instance(); UserResourceController(); + void renderFrameCreated(content::RenderFrame *); void renderViewCreated(content::RenderView *); - void renderViewDestroyed(content::RenderView *); + void renderViewDestroyed(content::RenderView *renderView); void addScriptForView(const UserScriptData &, content::RenderView *); void removeScriptForView(const UserScriptData &, content::RenderView *); void clearScriptsForView(content::RenderView *); @@ -73,6 +74,7 @@ public: private: Q_DISABLE_COPY(UserResourceController) + class RenderFrameObserverHelper; class RenderViewObserverHelper; // RenderProcessObserver implementation. @@ -89,7 +91,7 @@ private: ViewUserScriptMap m_viewUserScriptMap; QHash<uint64_t, UserScriptData> m_scripts; - friend class RenderViewObserverHelper; + friend class RenderFrameObserverHelper; }; #endif // USER_RESOURCE_CONTROLLER_H diff --git a/src/core/renderer/web_channel_ipc_transport.cpp b/src/core/renderer/web_channel_ipc_transport.cpp index f34e1310b..cec8344b6 100644 --- a/src/core/renderer/web_channel_ipc_transport.cpp +++ b/src/core/renderer/web_channel_ipc_transport.cpp @@ -105,9 +105,9 @@ void WebChannelTransport::Install(blink::WebFrame *frame, uint worldId) v8::HandleScope handleScope(isolate); v8::Handle<v8::Context> context; if (worldId == 0) - context = frame->mainWorldScriptContext(); + context = frame->MainWorldScriptContext(); else - context = frame->toWebLocalFrame()->isolatedWorldScriptContext(worldId); + context = frame->ToWebLocalFrame()->IsolatedWorldScriptContext(worldId); v8::Context::Scope contextScope(context); gin::Handle<WebChannelTransport> transport = gin::CreateHandle(isolate, new WebChannelTransport); @@ -126,9 +126,9 @@ void WebChannelTransport::Uninstall(blink::WebFrame *frame, uint worldId) v8::HandleScope handleScope(isolate); v8::Handle<v8::Context> context; if (worldId == 0) - context = frame->mainWorldScriptContext(); + context = frame->MainWorldScriptContext(); else - context = frame->toWebLocalFrame()->isolatedWorldScriptContext(worldId); + context = frame->ToWebLocalFrame()->IsolatedWorldScriptContext(worldId); v8::Context::Scope contextScope(context); v8::Handle<v8::Object> global(context->Global()); @@ -145,12 +145,12 @@ gin::ObjectTemplateBuilder WebChannelTransport::GetObjectTemplateBuilder(v8::Iso content::RenderView *WebChannelTransport::GetRenderView(v8::Isolate *isolate) { - blink::WebLocalFrame *webframe = blink::WebLocalFrame::frameForContext(isolate->GetCurrentContext()); + blink::WebLocalFrame *webframe = blink::WebLocalFrame::FrameForContext(isolate->GetCurrentContext()); DCHECK(webframe) << "There should be an active frame since we just got a native function called."; if (!webframe) return 0; - blink::WebView *webview = webframe->view(); + blink::WebView *webview = webframe->View(); if (!webview) return 0; // can happen during closing @@ -179,7 +179,7 @@ void WebChannelIPCTransport::installWebChannel(uint worldId) blink::WebView *webView = render_view()->GetWebView(); if (!webView) return; - WebChannelTransport::Install(webView->mainFrame(), worldId); + WebChannelTransport::Install(webView->MainFrame(), worldId); m_installed = true; m_installedWorldId = worldId; } @@ -190,7 +190,7 @@ void WebChannelIPCTransport::uninstallWebChannel(uint worldId) blink::WebView *webView = render_view()->GetWebView(); if (!webView) return; - WebChannelTransport::Uninstall(webView->mainFrame(), worldId); + WebChannelTransport::Uninstall(webView->MainFrame(), worldId); m_installed = false; } @@ -206,12 +206,12 @@ void WebChannelIPCTransport::dispatchWebChannelMessage(const std::vector<char> & v8::Isolate *isolate = v8::Isolate::GetCurrent(); v8::HandleScope handleScope(isolate); - blink::WebFrame *frame = webView->mainFrame(); + blink::WebFrame *frame = webView->MainFrame(); v8::Handle<v8::Context> context; if (worldId == 0) - context = frame->mainWorldScriptContext(); + context = frame->MainWorldScriptContext(); else - context = frame->toWebLocalFrame()->isolatedWorldScriptContext(worldId); + context = frame->ToWebLocalFrame()->IsolatedWorldScriptContext(worldId); v8::Context::Scope contextScope(context); v8::Handle<v8::Object> global(context->Global()); @@ -239,7 +239,7 @@ void WebChannelIPCTransport::dispatchWebChannelMessage(const std::vector<char> & const int argc = 1; v8::Handle<v8::Value> argv[argc]; argv[0] = messageObject; - frame->callFunctionEvenIfScriptDisabled(callback, webChannelObjectValue->ToObject(), argc, argv); + frame->CallFunctionEvenIfScriptDisabled(callback, webChannelObjectValue->ToObject(), argc, argv); } bool WebChannelIPCTransport::OnMessageReceived(const IPC::Message &message) @@ -254,4 +254,9 @@ bool WebChannelIPCTransport::OnMessageReceived(const IPC::Message &message) return handled; } +void WebChannelIPCTransport::OnDestruct() +{ + delete this; +} + } // namespace diff --git a/src/core/renderer/web_channel_ipc_transport.h b/src/core/renderer/web_channel_ipc_transport.h index a2c7d5b4e..04041c6c7 100644 --- a/src/core/renderer/web_channel_ipc_transport.h +++ b/src/core/renderer/web_channel_ipc_transport.h @@ -71,7 +71,7 @@ private: // content::RenderViewObserver overrides: bool OnMessageReceived(const IPC::Message &message) override; - void OnDestruct() override { } + void OnDestruct() override; bool m_installed; uint m_installedWorldId; diff --git a/src/core/renderer_host/user_resource_controller_host.cpp b/src/core/renderer_host/user_resource_controller_host.cpp index 0a6decaf9..2799d5d85 100644 --- a/src/core/renderer_host/user_resource_controller_host.cpp +++ b/src/core/renderer_host/user_resource_controller_host.cpp @@ -47,6 +47,7 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host_observer.h" #include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" @@ -57,8 +58,9 @@ public: WebContentsObserverHelper(UserResourceControllerHost *, content::WebContents *); // WebContentsObserver overrides: - void RenderViewCreated(content::RenderViewHost *renderViewHost) override; - void RenderViewHostChanged(content::RenderViewHost *oldHost, content::RenderViewHost *newHost) override; + void RenderFrameCreated(content::RenderFrameHost *renderFrameHost) override; + void RenderFrameHostChanged(content::RenderFrameHost *oldHost, + content::RenderFrameHost *newHost) override; void WebContentsDestroyed() override; private: @@ -71,22 +73,21 @@ UserResourceControllerHost::WebContentsObserverHelper::WebContentsObserverHelper { } -void UserResourceControllerHost::WebContentsObserverHelper::RenderViewCreated(content::RenderViewHost *renderViewHost) +void UserResourceControllerHost::WebContentsObserverHelper::RenderFrameCreated( + content::RenderFrameHost *renderFrameHost) { content::WebContents *contents = web_contents(); Q_FOREACH (const UserScript &script, m_controllerHost->m_perContentsScripts.value(contents)) - renderViewHost->Send(new RenderViewObserverHelper_AddScript(renderViewHost->GetRoutingID(), script.data())); + renderFrameHost->Send(new RenderFrameObserverHelper_AddScript( + renderFrameHost->GetRoutingID(), script.data())); } -void UserResourceControllerHost::WebContentsObserverHelper::RenderViewHostChanged(content::RenderViewHost *oldHost, - content::RenderViewHost *newHost) +void UserResourceControllerHost::WebContentsObserverHelper::RenderFrameHostChanged( + content::RenderFrameHost *oldHost, + content::RenderFrameHost *newHost) { if (oldHost) - oldHost->Send(new RenderViewObserverHelper_ClearScripts(oldHost->GetRoutingID())); - - content::WebContents *contents = web_contents(); - Q_FOREACH (const UserScript &script, m_controllerHost->m_perContentsScripts.value(contents)) - newHost->Send(new RenderViewObserverHelper_AddScript(newHost->GetRoutingID(), script.data())); + oldHost->Send(new RenderFrameObserverHelper_ClearScripts(oldHost->GetRoutingID())); } void UserResourceControllerHost::WebContentsObserverHelper::WebContentsDestroyed() @@ -119,7 +120,8 @@ void UserResourceControllerHost::addUserScript(const UserScript &script, WebCont if (script.isNull()) return; // Global scripts should be dispatched to all our render processes. - if (!adapter) { + const bool isProfileWideScript = !adapter; + if (isProfileWideScript) { if (!m_profileWideScripts.contains(script)) { m_profileWideScripts.append(script); Q_FOREACH (content::RenderProcessHost *renderer, m_observedProcesses) @@ -140,7 +142,9 @@ void UserResourceControllerHost::addUserScript(const UserScript &script, WebCont m_perContentsScripts.insert(contents, currentScripts); } } - contents->Send(new RenderViewObserverHelper_AddScript(contents->GetRenderViewHost()->GetRoutingID(), script.data())); + contents->Send(new RenderFrameObserverHelper_AddScript(contents->GetRenderViewHost()-> + GetMainFrame()->GetRoutingID(), + script.data())); } } @@ -149,7 +153,8 @@ bool UserResourceControllerHost::containsUserScript(const UserScript &script, We if (script.isNull()) return false; // Global scripts should be dispatched to all our render processes. - if (!adapter) + const bool isProfileWideScript = !adapter; + if (isProfileWideScript) return m_profileWideScripts.contains(script); return m_perContentsScripts.value(adapter->webContents()).contains(script); } @@ -158,7 +163,8 @@ bool UserResourceControllerHost::removeUserScript(const UserScript &script, WebC { if (script.isNull()) return false; - if (!adapter) { + const bool isProfileWideScript = !adapter; + if (isProfileWideScript) { QList<UserScript>::iterator it = std::find(m_profileWideScripts.begin(), m_profileWideScripts.end(), script); if (it == m_profileWideScripts.end()) @@ -174,7 +180,9 @@ bool UserResourceControllerHost::removeUserScript(const UserScript &script, WebC QList<UserScript>::iterator it = std::find(list.begin(), list.end(), script); if (it == list.end()) return false; - contents->Send(new RenderViewObserverHelper_RemoveScript(contents->GetRenderViewHost()->GetRoutingID(), (*it).data())); + contents->Send(new RenderFrameObserverHelper_RemoveScript(contents-> + GetMainFrame()->GetRoutingID(), + (*it).data())); list.erase(it); } return true; @@ -182,27 +190,31 @@ bool UserResourceControllerHost::removeUserScript(const UserScript &script, WebC void UserResourceControllerHost::clearAllScripts(WebContentsAdapter *adapter) { - if (!adapter) { + const bool isProfileWideScript = !adapter; + if (isProfileWideScript) { m_profileWideScripts.clear(); Q_FOREACH (content::RenderProcessHost *renderer, m_observedProcesses) renderer->Send(new UserResourceController_ClearScripts); } else { content::WebContents *contents = adapter->webContents(); m_perContentsScripts.remove(contents); - contents->Send(new RenderViewObserverHelper_ClearScripts(contents->GetRenderViewHost()->GetRoutingID())); + contents->Send(new RenderFrameObserverHelper_ClearScripts(contents-> + GetMainFrame()->GetRoutingID())); } } const QList<UserScript> UserResourceControllerHost::registeredScripts(WebContentsAdapter *adapter) const { - if (!adapter) + const bool isProfileWideScript = !adapter; + if (isProfileWideScript) return m_profileWideScripts; return m_perContentsScripts.value(adapter->webContents()); } void UserResourceControllerHost::reserve(WebContentsAdapter *adapter, int count) { - if (!adapter) + const bool isProfileWideScript = !adapter; + if (isProfileWideScript) m_profileWideScripts.reserve(count); else m_perContentsScripts[adapter->webContents()].reserve(count); diff --git a/src/core/renderer_host/web_channel_ipc_transport_host.cpp b/src/core/renderer_host/web_channel_ipc_transport_host.cpp index 1cd4e4063..c47b255b7 100644 --- a/src/core/renderer_host/web_channel_ipc_transport_host.cpp +++ b/src/core/renderer_host/web_channel_ipc_transport_host.cpp @@ -40,6 +40,7 @@ #include "web_channel_ipc_transport_host.h" #include "base/strings/string16.h" +#include "content/public/browser/render_view_host.h" #include "common/qt_messages.h" #include "type_conversion.h" @@ -61,11 +62,16 @@ WebChannelIPCTransportHost::~WebChannelIPCTransportHost() { } -void WebChannelIPCTransportHost::RenderViewHostChanged(content::RenderViewHost *, content::RenderViewHost *) +void WebChannelIPCTransportHost::RenderViewHostChanged(content::RenderViewHost *oldHost, content::RenderViewHost *) { - // This means that we were moved into a different RenderView, possibly in a different - // render process and that we lost our WebChannelIPCTransport object and its state. - Send(new WebChannelIPCTransport_Install(routing_id(), m_worldId)); + if (oldHost) + oldHost->Send(new WebChannelIPCTransport_Uninstall(oldHost->GetRoutingID(), m_worldId)); +} + +void WebChannelIPCTransportHost::RenderViewCreated(content::RenderViewHost *view_host) +{ + // Make sure the new view knows a webchannel is installed and in which world. + view_host->Send(new WebChannelIPCTransport_Install(view_host->GetRoutingID(), m_worldId)); } void WebChannelIPCTransportHost::setWorldId(uint worldId) diff --git a/src/core/renderer_host/web_channel_ipc_transport_host.h b/src/core/renderer_host/web_channel_ipc_transport_host.h index aa406471c..a1e697a91 100644 --- a/src/core/renderer_host/web_channel_ipc_transport_host.h +++ b/src/core/renderer_host/web_channel_ipc_transport_host.h @@ -60,6 +60,7 @@ public: // WebContentsObserver void RenderViewHostChanged(content::RenderViewHost* old_host, content::RenderViewHost* new_host) override; + void RenderViewCreated(content::RenderViewHost* render_view_host) override; // QWebChannelAbstractTransport void sendMessage(const QJsonObject &message) override; diff --git a/src/core/surface_factory_qt.cpp b/src/core/surface_factory_qt.cpp index 9e72885c3..6e5e13866 100644 --- a/src/core/surface_factory_qt.cpp +++ b/src/core/surface_factory_qt.cpp @@ -56,13 +56,7 @@ #if defined(USE_OZONE) #include <EGL/egl.h> - -#ifndef QT_LIBDIR_EGL -#define QT_LIBDIR_EGL "/usr/lib" -#endif -#ifndef QT_LIBDIR_GLES2 -#define QT_LIBDIR_GLES2 QT_LIBDIR_EGL -#endif +#include <dlfcn.h> namespace QtWebEngineCore { @@ -99,29 +93,21 @@ base::NativeLibrary LoadLibrary(const base::FilePath& filename) { bool GLOzoneQt::LoadGLES2Bindings() { - base::FilePath libEGLPath = QtWebEngineCore::toFilePath(QT_LIBDIR_EGL); - libEGLPath = libEGLPath.Append("libEGL.so.1"); - base::NativeLibrary eglLibrary = LoadLibrary(libEGLPath); - if (!eglLibrary) - return false; - - base::FilePath libGLES2Path = QtWebEngineCore::toFilePath(QT_LIBDIR_GLES2); - libGLES2Path = libGLES2Path.Append("libGLESv2.so.2"); - base::NativeLibrary gles2Library = LoadLibrary(libGLES2Path); - if (!gles2Library) + base::NativeLibrary eglgles2Library = dlopen(NULL, RTLD_LAZY); + if (!eglgles2Library) { + LOG(ERROR) << "Failed to open EGL/GLES2 context " << dlerror(); return false; + } - gl::GLGetProcAddressProc get_proc_address = reinterpret_cast<gl::GLGetProcAddressProc>(base::GetFunctionPointerFromNativeLibrary(eglLibrary, "eglGetProcAddress")); + gl::GLGetProcAddressProc get_proc_address = reinterpret_cast<gl::GLGetProcAddressProc>(base::GetFunctionPointerFromNativeLibrary(eglgles2Library, "eglGetProcAddress")); if (!get_proc_address) { LOG(ERROR) << "eglGetProcAddress not found."; - base::UnloadNativeLibrary(eglLibrary); - base::UnloadNativeLibrary(gles2Library); + base::UnloadNativeLibrary(eglgles2Library); return false; } gl::SetGLGetProcAddressProc(get_proc_address); - gl::AddGLNativeLibrary(eglLibrary); - gl::AddGLNativeLibrary(gles2Library); + gl::AddGLNativeLibrary(eglgles2Library); return true; } diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp index fe1758655..8a6717e91 100644 --- a/src/core/url_request_context_getter_qt.cpp +++ b/src/core/url_request_context_getter_qt.cpp @@ -189,9 +189,9 @@ void URLRequestContextGetterQt::cancelAllUrlRequests() Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); Q_ASSERT(m_urlRequestContext); - std::set<const net::URLRequest*>* url_requests = m_urlRequestContext->url_requests(); - std::set<const net::URLRequest*>::const_iterator it = url_requests->begin(); - std::set<const net::URLRequest*>::const_iterator end = url_requests->end(); + const std::set<const net::URLRequest*>& url_requests = m_urlRequestContext->url_requests(); + std::set<const net::URLRequest*>::const_iterator it = url_requests.begin(); + std::set<const net::URLRequest*>::const_iterator end = url_requests.end(); for ( ; it != end; ++it) { net::URLRequest* request = const_cast<net::URLRequest*>(*it); if (request) diff --git a/src/core/url_request_custom_job.cpp b/src/core/url_request_custom_job.cpp index d093efd0a..47c9b3b4c 100644 --- a/src/core/url_request_custom_job.cpp +++ b/src/core/url_request_custom_job.cpp @@ -38,69 +38,63 @@ ****************************************************************************/ #include "url_request_custom_job.h" -#include "url_request_custom_job_delegate.h" - -#include "api/qwebengineurlrequestjob.h" -#include "api/qwebengineurlschemehandler.h" -#include "browser_context_adapter.h" -#include "type_conversion.h" - +#include "url_request_custom_job_proxy.h" #include "content/public/browser/browser_thread.h" -#include "net/base/net_errors.h" #include "net/base/io_buffer.h" -#include <QFileInfo> -#include <QMimeDatabase> -#include <QMimeType> -#include <QUrl> +#include <QIODevice> using namespace net; namespace QtWebEngineCore { -URLRequestCustomJob::URLRequestCustomJob(URLRequest *request, NetworkDelegate *networkDelegate, - const std::string &scheme, QWeakPointer<const BrowserContextAdapter> adapter) +URLRequestCustomJob::URLRequestCustomJob(URLRequest *request, + NetworkDelegate *networkDelegate, + const std::string &scheme, + QWeakPointer<const BrowserContextAdapter> adapter) : URLRequestJob(request, networkDelegate) - , m_scheme(scheme) - , m_adapter(adapter) - , m_shared(new URLRequestCustomJobShared(this)) + , m_proxy(new URLRequestCustomJobProxy(this, scheme, adapter)) + , m_device(nullptr) + , m_error(0) { } URLRequestCustomJob::~URLRequestCustomJob() { - if (m_shared) - m_shared->killJob(); -} - -static void startAsync(URLRequestCustomJobShared *shared) -{ - shared->startAsync(); + m_proxy->m_job = nullptr; + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::release, + m_proxy)); + if (m_device && m_device->isOpen()) + m_device->close(); + m_device = nullptr; } void URLRequestCustomJob::Start() { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, base::Bind(&startAsync, m_shared)); + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::initialize, + m_proxy, request()->url(), request()->method())); } void URLRequestCustomJob::Kill() { - if (m_shared) - m_shared->killJob(); - m_shared = 0; - + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + if (m_device && m_device->isOpen()) + m_device->close(); + m_device = nullptr; + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::release, + m_proxy)); URLRequestJob::Kill(); } bool URLRequestCustomJob::GetMimeType(std::string *mimeType) const { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - if (!m_shared) - return false; - QMutexLocker lock(&m_shared->m_mutex); - if (m_shared->m_mimeType.size() > 0) { - *mimeType = m_shared->m_mimeType; + if (m_mimeType.size() > 0) { + *mimeType = m_mimeType; return true; } return false; @@ -109,11 +103,8 @@ bool URLRequestCustomJob::GetMimeType(std::string *mimeType) const bool URLRequestCustomJob::GetCharset(std::string* charset) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - if (!m_shared) - return false; - QMutexLocker lock(&m_shared->m_mutex); - if (m_shared->m_charset.size() > 0) { - *charset = m_shared->m_charset; + if (m_charset.size() > 0) { + *charset = m_charset; return true; } return false; @@ -122,11 +113,8 @@ bool URLRequestCustomJob::GetCharset(std::string* charset) bool URLRequestCustomJob::IsRedirectResponse(GURL* location, int* http_status_code) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - if (!m_shared) - return false; - QMutexLocker lock(&m_shared->m_mutex); - if (m_shared->m_redirect.is_valid()) { - *location = m_shared->m_redirect; + if (m_redirect.is_valid()) { + *location = m_redirect; *http_status_code = 303; return true; } @@ -136,224 +124,16 @@ bool URLRequestCustomJob::IsRedirectResponse(GURL* location, int* http_status_co int URLRequestCustomJob::ReadRawData(IOBuffer *buf, int bufSize) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - Q_ASSERT(m_shared); - QMutexLocker lock(&m_shared->m_mutex); - if (m_shared->m_error) - return m_shared->m_error; - qint64 rv = m_shared->m_device ? m_shared->m_device->read(buf->data(), bufSize) : -1; - if (rv >= 0) + if (m_error) + return m_error; + qint64 rv = m_device ? m_device->read(buf->data(), bufSize) : -1; + if (rv >= 0) { return static_cast<int>(rv); - else { + } else { // QIODevice::read might have called fail on us. - if (m_shared->m_error) - return m_shared->m_error; + if (m_error) + return m_error; return ERR_FAILED; } } - - -URLRequestCustomJobShared::URLRequestCustomJobShared(URLRequestCustomJob *job) - : m_mutex(QMutex::Recursive) - , m_job(job) - , m_delegate(0) - , m_error(0) - , m_started(false) - , m_asyncInitialized(false) - , m_weakFactory(this) -{ -} - -URLRequestCustomJobShared::~URLRequestCustomJobShared() -{ - Q_ASSERT(!m_job); - Q_ASSERT(!m_delegate); -} - -void URLRequestCustomJobShared::killJob() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - QMutexLocker lock(&m_mutex); - m_job = 0; - bool doDelete = false; - if (m_delegate) { - m_delegate->deleteLater(); - } else { - // Do not delete yet if startAsync has not yet run. - doDelete = m_asyncInitialized; - } - if (m_device && m_device->isOpen()) - m_device->close(); - m_device = 0; - m_weakFactory.InvalidateWeakPtrs(); - lock.unlock(); - if (doDelete) - delete this; -} - -void URLRequestCustomJobShared::unsetJobDelegate() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - QMutexLocker lock(&m_mutex); - m_delegate = 0; - bool doDelete = false; - if (m_job) - abort(); - else - doDelete = true; - lock.unlock(); - if (doDelete) - delete this; -} - -void URLRequestCustomJobShared::setReplyMimeType(const std::string &mimeType) -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - QMutexLocker lock(&m_mutex); - m_mimeType = mimeType; -} - -void URLRequestCustomJobShared::setReplyCharset(const std::string &charset) -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - QMutexLocker lock(&m_mutex); - m_charset = charset; -} - -void URLRequestCustomJobShared::setReplyDevice(QIODevice *device) -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - QMutexLocker lock(&m_mutex); - if (!m_job) - return; - m_device = device; - if (m_device && !m_device->isReadable()) - m_device->open(QIODevice::ReadOnly); - - qint64 size = m_device ? m_device->size() : -1; - if (size > 0) - m_job->set_expected_content_size(size); - if (m_device && m_device->isReadable()) - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyStarted, m_weakFactory.GetWeakPtr())); - else - fail(ERR_INVALID_URL); -} - -void URLRequestCustomJobShared::redirect(const GURL &url) -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - QMutexLocker lock(&m_mutex); - if (m_device || m_error) - return; - if (!m_job) - return; - m_redirect = url; - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyStarted, m_weakFactory.GetWeakPtr())); -} - -void URLRequestCustomJobShared::abort() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - QMutexLocker lock(&m_mutex); - if (m_device && m_device->isOpen()) - m_device->close(); - m_device = 0; - if (!m_job) - return; - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyCanceled, m_weakFactory.GetWeakPtr())); -} - -void URLRequestCustomJobShared::notifyCanceled() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - QMutexLocker lock(&m_mutex); - if (!m_job) - return; - if (m_started) - m_job->NotifyCanceled(); - else - m_job->NotifyStartError(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED)); -} - -void URLRequestCustomJobShared::notifyStarted() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - QMutexLocker lock(&m_mutex); - if (!m_job) - return; - Q_ASSERT(!m_started); - m_started = true; - m_job->NotifyHeadersComplete(); -} - -void URLRequestCustomJobShared::fail(int error) -{ - QMutexLocker lock(&m_mutex); - m_error = error; - if (content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) - return; - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (!m_job) - return; - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyFailure, m_weakFactory.GetWeakPtr())); -} - -void URLRequestCustomJobShared::notifyFailure() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - QMutexLocker lock(&m_mutex); - if (!m_job) - return; - if (m_device) - m_device->close(); - if (!m_started) - m_job->NotifyStartError(URLRequestStatus::FromError(m_error)); - // else we fail on the next read, or the read that might already be in progress -} - -GURL URLRequestCustomJobShared::requestUrl() -{ - QMutexLocker lock(&m_mutex); - if (!m_job) - return GURL(); - return m_job->request()->url(); -} - -std::string URLRequestCustomJobShared::requestMethod() -{ - QMutexLocker lock(&m_mutex); - if (!m_job) - return std::string(); - return m_job->request()->method(); -} - -void URLRequestCustomJobShared::startAsync() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - Q_ASSERT(!m_started); - Q_ASSERT(!m_delegate); - QMutexLocker lock(&m_mutex); - if (!m_job) { - lock.unlock(); - delete this; - return; - } - - QWebEngineUrlSchemeHandler *schemeHandler = 0; - QSharedPointer<const BrowserContextAdapter> browserContext = m_job->m_adapter.toStrongRef(); - if (browserContext) - schemeHandler = browserContext->customUrlSchemeHandlers()[toQByteArray(m_job->m_scheme)]; - if (schemeHandler) { - m_delegate = new URLRequestCustomJobDelegate(this); - m_asyncInitialized = true; - QWebEngineUrlRequestJob *requestJob = new QWebEngineUrlRequestJob(m_delegate); - schemeHandler->requestStarted(requestJob); - } else { - lock.unlock(); - abort(); - delete this; - return; - } -} - } // namespace diff --git a/src/core/url_request_custom_job.h b/src/core/url_request_custom_job.h index 93edb0b8c..68a834d48 100644 --- a/src/core/url_request_custom_job.h +++ b/src/core/url_request_custom_job.h @@ -40,11 +40,9 @@ #ifndef URL_REQUEST_CUSTOM_JOB_H_ #define URL_REQUEST_CUSTOM_JOB_H_ -#include "net/url_request/url_request.h" #include "net/url_request/url_request_job.h" - -#include <QtCore/QMutex> -#include <QtCore/QPointer> +#include "url/gurl.h" +#include <QtCore/QWeakPointer> QT_FORWARD_DECLARE_CLASS(QIODevice) @@ -52,12 +50,15 @@ namespace QtWebEngineCore { class BrowserContextAdapter; class URLRequestCustomJobDelegate; -class URLRequestCustomJobShared; +class URLRequestCustomJobProxy; // A request job that handles reading custom URL schemes class URLRequestCustomJob : public net::URLRequestJob { public: - URLRequestCustomJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate, const std::string &scheme, QWeakPointer<const BrowserContextAdapter> adapter); + URLRequestCustomJob(net::URLRequest *request, + net::NetworkDelegate *networkDelegate, + const std::string &scheme, + QWeakPointer<const BrowserContextAdapter> adapter); void Start() override; void Kill() override; int ReadRawData(net::IOBuffer *buf, int buf_size) override; @@ -69,54 +70,17 @@ protected: virtual ~URLRequestCustomJob(); private: - std::string m_scheme; - QWeakPointer<const BrowserContextAdapter> m_adapter; - URLRequestCustomJobShared *m_shared; - - friend class URLRequestCustomJobShared; - - DISALLOW_COPY_AND_ASSIGN(URLRequestCustomJob); -}; - -// A shared state between URLRequestCustomJob living on the IO thread -// and URLRequestCustomJobDelegate living on the UI thread. -class URLRequestCustomJobShared { -public: - URLRequestCustomJobShared(URLRequestCustomJob *job); - ~URLRequestCustomJobShared(); - - void setReplyMimeType(const std::string &); - void setReplyCharset(const std::string &); - void setReplyDevice(QIODevice *); - - void redirect(const GURL &url); - void fail(int); - void abort(); - - void killJob(); - void unsetJobDelegate(); - - void startAsync(); - void notifyStarted(); - void notifyFailure(); - void notifyCanceled(); - - GURL requestUrl(); - std::string requestMethod(); - - QMutex m_mutex; - QPointer<QIODevice> m_device; - URLRequestCustomJob *m_job; - URLRequestCustomJobDelegate *m_delegate; + scoped_refptr<URLRequestCustomJobProxy> m_proxy; std::string m_mimeType; std::string m_charset; - int m_error; GURL m_redirect; - bool m_started; - bool m_asyncInitialized; - base::WeakPtrFactory<URLRequestCustomJobShared> m_weakFactory; -}; + QIODevice *m_device; + int m_error; + + friend class URLRequestCustomJobProxy; + DISALLOW_COPY_AND_ASSIGN(URLRequestCustomJob); +}; } // namespace QtWebEngineCore #endif // URL_REQUEST_CUSTOM_JOB_H_ diff --git a/src/core/url_request_custom_job_delegate.cpp b/src/core/url_request_custom_job_delegate.cpp index 7e806a4e0..14de9a812 100644 --- a/src/core/url_request_custom_job_delegate.cpp +++ b/src/core/url_request_custom_job_delegate.cpp @@ -37,50 +37,59 @@ ** ****************************************************************************/ -#include "url_request_custom_job.h" #include "url_request_custom_job_delegate.h" +#include "url_request_custom_job_proxy.h" #include "type_conversion.h" #include "net/base/net_errors.h" +#include "content/public/browser/browser_thread.h" #include <QByteArray> namespace QtWebEngineCore { -URLRequestCustomJobDelegate::URLRequestCustomJobDelegate(URLRequestCustomJobShared *shared) - : m_shared(shared) +URLRequestCustomJobDelegate::URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy, + const QUrl &url, + const QByteArray &method) + : m_proxy(proxy), + m_request(url), + m_method(method) { } URLRequestCustomJobDelegate::~URLRequestCustomJobDelegate() { - m_shared->unsetJobDelegate(); } QUrl URLRequestCustomJobDelegate::url() const { - return toQt(m_shared->requestUrl()); + return m_request; } QByteArray URLRequestCustomJobDelegate::method() const { - return QByteArray::fromStdString(m_shared->requestMethod()); + return m_method; } -void URLRequestCustomJobDelegate::setReply(const QByteArray &contentType, QIODevice *device) +void URLRequestCustomJobDelegate::reply(const QByteArray &contentType, QIODevice *device) { - m_shared->setReplyMimeType(contentType.toStdString()); - m_shared->setReplyDevice(device); + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::reply, + m_proxy,contentType.toStdString(),device)); } void URLRequestCustomJobDelegate::abort() { - m_shared->abort(); + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::abort, + m_proxy)); } void URLRequestCustomJobDelegate::redirect(const QUrl &url) { - m_shared->redirect(toGurl(url)); + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::redirect, + m_proxy, toGurl(url))); } void URLRequestCustomJobDelegate::fail(Error error) @@ -105,8 +114,11 @@ void URLRequestCustomJobDelegate::fail(Error error) net_error = net::ERR_FAILED; break; } - if (net_error) - m_shared->fail(net_error); + if (net_error) { + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::fail, + m_proxy, net_error)); + } } } // namespace diff --git a/src/core/url_request_custom_job_delegate.h b/src/core/url_request_custom_job_delegate.h index 7752d979e..eb99f3576 100644 --- a/src/core/url_request_custom_job_delegate.h +++ b/src/core/url_request_custom_job_delegate.h @@ -40,6 +40,7 @@ #ifndef URL_REQUEST_CUSTOM_JOB_DELEGATE_H_ #define URL_REQUEST_CUSTOM_JOB_DELEGATE_H_ +#include "base/memory/ref_counted.h" #include "qtwebenginecoreglobal.h" #include <QObject> @@ -49,7 +50,7 @@ QT_FORWARD_DECLARE_CLASS(QIODevice) namespace QtWebEngineCore { -class URLRequestCustomJobShared; +class URLRequestCustomJobProxy; class QWEBENGINE_EXPORT URLRequestCustomJobDelegate : public QObject { Q_OBJECT @@ -68,17 +69,20 @@ public: QUrl url() const; QByteArray method() const; - void setReply(const QByteArray &contentType, QIODevice *device); + void reply(const QByteArray &contentType, QIODevice *device); void redirect(const QUrl& url); void abort(); - void fail(Error); private: - URLRequestCustomJobDelegate(URLRequestCustomJobShared *shared); + URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy, + const QUrl &url, + const QByteArray &method); - friend class URLRequestCustomJobShared; - URLRequestCustomJobShared *m_shared; + friend class URLRequestCustomJobProxy; + scoped_refptr<URLRequestCustomJobProxy> m_proxy; + QUrl m_request; + QByteArray m_method; }; } // namespace diff --git a/src/core/url_request_custom_job_proxy.cpp b/src/core/url_request_custom_job_proxy.cpp new file mode 100644 index 000000000..d53602c85 --- /dev/null +++ b/src/core/url_request_custom_job_proxy.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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 "url_request_custom_job_proxy.h" +#include "url_request_custom_job.h" +#include "url_request_custom_job_delegate.h" +#include "api/qwebengineurlrequestjob.h" +#include "browser_context_adapter.h" +#include "type_conversion.h" +#include "content/public/browser/browser_thread.h" + +using namespace net; + +namespace QtWebEngineCore { + +URLRequestCustomJobProxy::URLRequestCustomJobProxy(URLRequestCustomJob *job, + const std::string &scheme, + QWeakPointer<const BrowserContextAdapter> adapter) + : m_job(job) + , m_started(false) + , m_scheme(scheme) + , m_delegate(nullptr) + , m_adapter(adapter) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); +} + +URLRequestCustomJobProxy::~URLRequestCustomJobProxy() +{ +} + +void URLRequestCustomJobProxy::release() +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (m_delegate) { + m_delegate->deleteLater(); + m_delegate = nullptr; + } +} + +// Fix me: this is never used +/* +void URLRequestCustomJobProxy::setReplyCharset(const std::string &charset) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + if (!m_job) + return; + m_job->m_charset = charset; +} +*/ +void URLRequestCustomJobProxy::reply(std::string mimeType, QIODevice *device) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + if (!m_job) + return; + m_job->m_mimeType = mimeType; + m_job->m_device = device; + if (m_job->m_device && !m_job->m_device->isReadable()) + m_job->m_device->open(QIODevice::ReadOnly); + + qint64 size = m_job->m_device ? m_job->m_device->size() : -1; + if (size > 0) + m_job->set_expected_content_size(size); + if (m_job->m_device && m_job->m_device->isReadable()) { + m_started = true; + m_job->NotifyHeadersComplete(); + } else { + fail(ERR_INVALID_URL); + } +} + +void URLRequestCustomJobProxy::redirect(GURL url) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + if (!m_job) + return; + if (m_job->m_device || m_job->m_error) + return; + m_job->m_redirect = url; + m_started = true; + m_job->NotifyHeadersComplete(); +} + +void URLRequestCustomJobProxy::abort() +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + if (!m_job) + return; + if (m_job->m_device && m_job->m_device->isOpen()) + m_job->m_device->close(); + m_job->m_device = nullptr; + if (m_started) + m_job->NotifyCanceled(); + else + m_job->NotifyStartError(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED)); +} + +void URLRequestCustomJobProxy::fail(int error) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + if (!m_job) + return; + m_job->m_error = error; + if (m_job->m_device) + m_job->m_device->close(); + if (!m_started) + m_job->NotifyStartError(URLRequestStatus::FromError(error)); + // else we fail on the next read, or the read that might already be in progress +} + +void URLRequestCustomJobProxy::initialize(GURL url, std::string method) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + Q_ASSERT(!m_delegate); + + QWebEngineUrlSchemeHandler *schemeHandler = 0; + QSharedPointer<const BrowserContextAdapter> browserContext = m_adapter.toStrongRef(); + if (browserContext) + schemeHandler = browserContext->customUrlSchemeHandlers()[toQByteArray(m_scheme)]; + if (schemeHandler) { + m_delegate = new URLRequestCustomJobDelegate(this, toQt(url), + QByteArray::fromStdString(method)); + QWebEngineUrlRequestJob *requestJob = new QWebEngineUrlRequestJob(m_delegate); + schemeHandler->requestStarted(requestJob); + } +} + +} // namespace diff --git a/src/core/url_request_custom_job_proxy.h b/src/core/url_request_custom_job_proxy.h new file mode 100644 index 000000000..df7171f5e --- /dev/null +++ b/src/core/url_request_custom_job_proxy.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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 URL_REQUEST_CUSTOM_JOB_PROXY_H_ +#define URL_REQUEST_CUSTOM_JOB_PROXY_H_ + +#include "base/memory/weak_ptr.h" +#include "url/gurl.h" +#include <QtCore/QWeakPointer> + +QT_FORWARD_DECLARE_CLASS(QIODevice) + +namespace QtWebEngineCore { + +class URLRequestCustomJob; +class URLRequestCustomJobDelegate; +class BrowserContextAdapter; + +// Used to comunicate between URLRequestCustomJob living on the IO thread +// and URLRequestCustomJobDelegate living on the UI thread. +class URLRequestCustomJobProxy + : public base::RefCountedThreadSafe<URLRequestCustomJobProxy> { + +public: + URLRequestCustomJobProxy(URLRequestCustomJob *job, + const std::string &scheme, + QWeakPointer<const BrowserContextAdapter> adapter); + ~URLRequestCustomJobProxy(); + + //void setReplyCharset(const std::string &); + void reply(std::string mimeType, QIODevice *device); + void redirect(GURL url); + void abort(); + void fail(int error); + void release(); + void initialize(GURL url, std::string method); + + //IO thread owned + URLRequestCustomJob *m_job; + bool m_started; + + //UI thread owned + std::string m_scheme; + URLRequestCustomJobDelegate *m_delegate; + QWeakPointer<const BrowserContextAdapter> m_adapter; +}; + +} // namespace QtWebEngineCore + +#endif // URL_REQUEST_CUSTOM_JOB_PROXY_H_ diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index c9b46b38a..2b7ab03dd 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -82,6 +82,8 @@ #include "content/public/common/web_preferences.h" #include "third_party/WebKit/public/web/WebFindOptions.h" #include "printing/features/features.h" +#include "ui/base/clipboard/clipboard.h" +#include "ui/base/clipboard/custom_data_helper.h" #include "ui/gfx/font_render_params.h" #include <QDir> @@ -92,6 +94,7 @@ #include <QVariant> #include <QtCore/qelapsedtimer.h> #include <QtCore/qmimedata.h> +#include <QtCore/qtemporarydir.h> #include <QtGui/qaccessible.h> #include <QtGui/qdrag.h> #include <QtGui/qpixmap.h> @@ -168,8 +171,7 @@ static QVariant fromJSValue(const base::Value *result) } case base::Value::Type::BINARY: { - const base::BinaryValue *out = static_cast<const base::BinaryValue*>(result); - QByteArray data(out->GetBuffer(), out->GetSize()); + QByteArray data(result->GetBlob().data(), result->GetBlob().size()); ret.setValue(data); break; } @@ -348,7 +350,7 @@ WebContentsAdapterPrivate::WebContentsAdapterPrivate() , adapterClient(0) , nextRequestId(CallbackDirectory::ReservedCallbackIdsEnd) , lastFindRequestId(0) - , currentDropAction(blink::WebDragOperationNone) + , currentDropAction(blink::kWebDragOperationNone) { } @@ -898,8 +900,8 @@ quint64 WebContentsAdapter::findText(const QString &subString, bool caseSensitiv blink::WebFindOptions options; options.forward = !findBackward; - options.matchCase = caseSensitively; - options.findNext = subString == d->webContentsDelegate->lastSearchedString(); + options.match_case = caseSensitively; + options.find_next = subString == d->webContentsDelegate->lastSearchedString(); d->webContentsDelegate->setLastSearchedString(subString); // Find already allows a request ID as input, but only as an int. @@ -926,7 +928,9 @@ void WebContentsAdapter::updateWebPreferences(const content::WebPreferences & we d->webContents->GetRenderViewHost()->UpdateWebkitPreferences(webPreferences); } -void WebContentsAdapter::download(const QUrl &url, const QString &suggestedFileName) +void WebContentsAdapter::download(const QUrl &url, const QString &suggestedFileName, + const QUrl &referrerUrl, + ReferrerPolicy referrerPolicy) { Q_D(WebContentsAdapter); content::BrowserContext *bctx = webContents()->GetBrowserContext(); @@ -939,9 +943,19 @@ void WebContentsAdapter::download(const QUrl &url, const QString &suggestedFileN dlmd->setDownloadType(BrowserContextAdapterClient::UserRequested); dlm->SetDelegate(dlmd); + GURL gurl = toGurl(url); std::unique_ptr<content::DownloadUrlParameters> params( - content::DownloadUrlParameters::CreateForWebContentsMainFrame(webContents(), toGurl(url))); + content::DownloadUrlParameters::CreateForWebContentsMainFrame(webContents(), gurl)); + params->set_suggested_name(toString16(suggestedFileName)); + + // referrer logic based on chrome/browser/renderer_context_menu/render_view_context_menu.cc: + params->set_referrer( + content::Referrer::SanitizeForRequest( + gurl, + content::Referrer(toGurl(referrerUrl).GetAsReferrer(), + static_cast<blink::WebReferrerPolicy>(referrerPolicy)))); + dlm->DownloadUrl(std::move(params)); } @@ -969,11 +983,11 @@ void WebContentsAdapter::copyImageAt(const QPoint &location) d->webContents->GetRenderViewHost()->GetMainFrame()->CopyImageAt(location.x(), location.y()); } -ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerNoAction, blink::WebMediaPlayerAction::Unknown) -ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerPlay, blink::WebMediaPlayerAction::Play) -ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerMute, blink::WebMediaPlayerAction::Mute) -ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerLoop, blink::WebMediaPlayerAction::Loop) -ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerControls, blink::WebMediaPlayerAction::Controls) +ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerNoAction, blink::WebMediaPlayerAction::kUnknown) +ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerPlay, blink::WebMediaPlayerAction::kPlay) +ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerMute, blink::WebMediaPlayerAction::kMute) +ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerLoop, blink::WebMediaPlayerAction::kLoop) +ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerControls, blink::WebMediaPlayerAction::kControls) void WebContentsAdapter::executeMediaPlayerActionAt(const QPoint &location, MediaPlayerAction action, bool enable) { @@ -1164,18 +1178,23 @@ static QMimeData *mimeDataFromDropData(const content::DropData &dropData) mimeData->setHtml(toQt(dropData.html.string())); if (dropData.url.is_valid()) mimeData->setUrls(QList<QUrl>() << toQt(dropData.url)); + if (!dropData.custom_data.empty()) { + base::Pickle pickle; + ui::WriteCustomDataToPickle(dropData.custom_data, &pickle); + mimeData->setData(toQt(ui::Clipboard::GetWebCustomDataFormatType().ToString()), QByteArray((const char*)pickle.data(), pickle.size())); + } return mimeData; } static blink::WebDragOperationsMask toWeb(const Qt::DropActions action) { - int result = blink::WebDragOperationNone; + int result = blink::kWebDragOperationNone; if (action & Qt::CopyAction) - result |= blink::WebDragOperationCopy; + result |= blink::kWebDragOperationCopy; if (action & Qt::LinkAction) - result |= blink::WebDragOperationLink; + result |= blink::kWebDragOperationLink; if (action & Qt::MoveAction) - result |= blink::WebDragOperationMove; + result |= blink::kWebDragOperationMove; return static_cast<blink::WebDragOperationsMask>(result); } @@ -1195,7 +1214,7 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD d->currentDropData->file_contents.clear(); d->currentDropData->file_contents_content_disposition.clear(); - d->currentDropAction = blink::WebDragOperationNone; + d->currentDropAction = blink::kWebDragOperationNone; QDrag *drag = new QDrag(dragSource); // will be deleted by Qt's DnD implementation bool dValid = true; QMetaObject::Connection onDestroyed = QObject::connect(dragSource, &QObject::destroyed, [&dValid](){ @@ -1203,7 +1222,11 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD QDrag::cancel(); }); - drag->setMimeData(mimeDataFromDropData(*d->currentDropData)); + QMimeData *mimeData = mimeDataFromDropData(*d->currentDropData); + if (handleDropDataFileContents(dropData, mimeData)) + allowedActions = Qt::MoveAction; + + drag->setMimeData(mimeData); if (!pixmap.isNull()) { drag->setPixmap(pixmap); drag->setHotSpot(offset); @@ -1229,6 +1252,36 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD } } +bool WebContentsAdapter::handleDropDataFileContents(const content::DropData &dropData, + QMimeData *mimeData) +{ + if (dropData.file_contents.empty()) + return false; + + Q_D(WebContentsAdapter); + if (!d->dndTmpDir) { + d->dndTmpDir.reset(new QTemporaryDir); + if (!d->dndTmpDir->isValid()) { + d->dndTmpDir.reset(); + return false; + } + } + + const auto maybeFilename = dropData.GetSafeFilenameForImageFileContents(); + const QString fileName = maybeFilename ? toQt(maybeFilename->AsUTF16Unsafe()) : QString(); + const QString &filePath = d->dndTmpDir->filePath(fileName); + QFile file(filePath); + if (!file.open(QIODevice::WriteOnly)) { + qWarning("Cannot write temporary file %s.", qUtf8Printable(filePath)); + return false; + } + file.write(QByteArray::fromStdString(dropData.file_contents)); + + const QUrl &targetUrl = QUrl::fromLocalFile(filePath); + mimeData->setUrls(QList<QUrl>{targetUrl}); + return true; +} + static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeData *mimeData) { Q_ASSERT(dropData->filenames.empty()); @@ -1245,6 +1298,10 @@ static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeDat dropData->html = toNullableString16(mimeData->html()); if (mimeData->hasText()) dropData->text = toNullableString16(mimeData->text()); + if (mimeData->hasFormat(toQt(ui::Clipboard::GetWebCustomDataFormatType().ToString()))) { + QByteArray customData = mimeData->data(toQt(ui::Clipboard::GetWebCustomDataFormatType().ToString())); + ui::ReadCustomDataIntoMap(customData.constData(), customData.length(), &dropData->custom_data); + } } void WebContentsAdapter::enterDrag(QDragEnterEvent *e, const QPoint &screenPos) @@ -1266,11 +1323,11 @@ void WebContentsAdapter::enterDrag(QDragEnterEvent *e, const QPoint &screenPos) Qt::DropAction toQt(blink::WebDragOperation op) { - if (op & blink::WebDragOperationCopy) + if (op & blink::kWebDragOperationCopy) return Qt::CopyAction; - if (op & blink::WebDragOperationLink) + if (op & blink::kWebDragOperationLink) return Qt::LinkAction; - if (op & blink::WebDragOperationMove || op & blink::WebDragOperationDelete) + if (op & blink::kWebDragOperationMove || op & blink::kWebDragOperationDelete) return Qt::MoveAction; return Qt::IgnoreAction; } @@ -1279,11 +1336,11 @@ static int toWeb(Qt::MouseButtons buttons) { int result = 0; if (buttons & Qt::LeftButton) - result |= blink::WebInputEvent::LeftButtonDown; + result |= blink::WebInputEvent::kLeftButtonDown; if (buttons & Qt::RightButton) - result |= blink::WebInputEvent::RightButtonDown; + result |= blink::WebInputEvent::kRightButtonDown; if (buttons & Qt::MiddleButton) - result |= blink::WebInputEvent::MiddleButtonDown; + result |= blink::WebInputEvent::kMiddleButtonDown; return result; } @@ -1291,13 +1348,13 @@ static int toWeb(Qt::KeyboardModifiers modifiers) { int result = 0; if (modifiers & Qt::ShiftModifier) - result |= blink::WebInputEvent::ShiftKey; + result |= blink::WebInputEvent::kShiftKey; if (modifiers & Qt::ControlModifier) - result |= blink::WebInputEvent::ControlKey; + result |= blink::WebInputEvent::kControlKey; if (modifiers & Qt::AltModifier) - result |= blink::WebInputEvent::AltKey; + result |= blink::WebInputEvent::kAltKey; if (modifiers & Qt::MetaModifier) - result |= blink::WebInputEvent::MetaKey; + result |= blink::WebInputEvent::kMetaKey; return result; } @@ -1439,4 +1496,13 @@ ASSERT_ENUMS_MATCH(WebContentsAdapterClient::SaveToDiskDisposition, WindowOpenDi ASSERT_ENUMS_MATCH(WebContentsAdapterClient::OffTheRecordDisposition, WindowOpenDisposition::OFF_THE_RECORD) ASSERT_ENUMS_MATCH(WebContentsAdapterClient::IgnoreActionDisposition, WindowOpenDisposition::IGNORE_ACTION) +ASSERT_ENUMS_MATCH(ReferrerPolicy::Always, blink::kWebReferrerPolicyAlways) +ASSERT_ENUMS_MATCH(ReferrerPolicy::Default, blink::kWebReferrerPolicyDefault) +ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngrade, blink::kWebReferrerPolicyNoReferrerWhenDowngrade) +ASSERT_ENUMS_MATCH(ReferrerPolicy::Never, blink::kWebReferrerPolicyNever) +ASSERT_ENUMS_MATCH(ReferrerPolicy::Origin, blink::kWebReferrerPolicyOrigin) +ASSERT_ENUMS_MATCH(ReferrerPolicy::OriginWhenCrossOrigin, blink::kWebReferrerPolicyOriginWhenCrossOrigin) +ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngradeOriginWhenCrossOrigin, blink::kWebReferrerPolicyNoReferrerWhenDowngradeOriginWhenCrossOrigin) +ASSERT_ENUMS_MATCH(ReferrerPolicy::Last, blink::kWebReferrerPolicyLast) + } // namespace QtWebEngineCore diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h index 10c65a6cb..67fcbe7af 100644 --- a/src/core/web_contents_adapter.h +++ b/src/core/web_contents_adapter.h @@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE class QAccessibleInterface; class QDragEnterEvent; class QDragMoveEvent; +class QMimeData; class QPageLayout; class QString; class QWebChannel; @@ -123,7 +124,9 @@ public: 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); + 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(); @@ -187,6 +190,7 @@ private: Q_DISABLE_COPY(WebContentsAdapter) Q_DECLARE_PRIVATE(WebContentsAdapter) void waitForUpdateDragActionCalled(); + bool handleDropDataFileContents(const content::DropData &dropData, QMimeData *mimeData); QScopedPointer<WebContentsAdapterPrivate> d_ptr; }; diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index 075f0a84b..47bef1b21 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -72,6 +72,17 @@ class WebContentsAdapter; class WebContentsDelegateQt; class WebEngineSettings; +// Must match blink::WebReferrerPolicy +enum class ReferrerPolicy { + Always, + Default, + NoReferrerWhenDowngrade, + Never, + Origin, + OriginWhenCrossOrigin, + NoReferrerWhenDowngradeOriginWhenCrossOrigin, + Last = NoReferrerWhenDowngradeOriginWhenCrossOrigin, +}; class WebEngineContextMenuSharedData : public QSharedData { @@ -98,6 +109,9 @@ public: QString suggestedFileName; QString misspelledWord; QStringList spellCheckerSuggestions; + QUrl pageUrl; + QUrl frameUrl; + ReferrerPolicy referrerPolicy = ReferrerPolicy::Default; // Some likely candidates for future additions as we add support for the related actions: // bool isImageBlocked; // <enum tbd> mediaType; @@ -254,6 +268,34 @@ public: return d->spellCheckerSuggestions; } + void setFrameUrl(const QUrl &url) { + d->frameUrl = url; + } + + QUrl frameUrl() const { + return d->frameUrl; + } + + void setPageUrl(const QUrl &url) { + d->pageUrl = url; + } + + QUrl pageUrl() const { + return d->pageUrl; + } + + QUrl referrerUrl() const { + return !d->frameUrl.isEmpty() ? d->frameUrl : d->pageUrl; + } + + void setReferrerPolicy(ReferrerPolicy referrerPolicy) { + d->referrerPolicy = referrerPolicy; + } + + ReferrerPolicy referrerPolicy() const { + return d->referrerPolicy; + } + private: QSharedDataPointer<WebEngineContextMenuSharedData> d; }; diff --git a/src/core/web_contents_adapter_p.h b/src/core/web_contents_adapter_p.h index f24070523..94f3ca08b 100644 --- a/src/core/web_contents_adapter_p.h +++ b/src/core/web_contents_adapter_p.h @@ -61,6 +61,7 @@ #include <QScopedPointer> #include <QSharedPointer> +QT_FORWARD_DECLARE_CLASS(QTemporaryDir) QT_FORWARD_DECLARE_CLASS(QWebChannel) class WebEngineContext; @@ -98,6 +99,7 @@ public: bool updateDragActionCalled; gfx::Point lastDragClientPos; gfx::Point lastDragScreenPos; + std::unique_ptr<QTemporaryDir> dndTmpDir; }; } // namespace QtWebEngineCore diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index b2df7e993..ad0e7ad6d 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -73,7 +73,6 @@ #include "content/public/common/frame_navigate_params.h" #include "content/public/common/url_constants.h" #include "content/public/common/web_preferences.h" -#include "ui/events/latency_info.h" #include <QDesktopServices> #include <QTimer> @@ -338,7 +337,7 @@ void WebContentsDelegateQt::DidUpdateFaviconURL(const std::vector<content::Favic m_faviconManager->update(faviconCandidates); } -void WebContentsDelegateQt::WebContentsCreated(content::WebContents* /*source_contents*/, int /*opener_render_process_id*/, int /*opener_render_frame_id*/, const std::string& /*frame_name*/, const GURL& target_url, content::WebContents* new_contents) +void WebContentsDelegateQt::WebContentsCreated(content::WebContents* /*source_contents*/, int /*opener_render_process_id*/, int /*opener_render_frame_id*/, const std::string& /*frame_name*/, const GURL& target_url, content::WebContents* new_contents, const base::Optional<content::WebContents::CreateParams>& create_params) { this->m_initialTargetUrl = toQt(target_url); } @@ -537,6 +536,10 @@ void WebContentsDelegateQt::BeforeUnloadFired(content::WebContents *tab, bool pr m_viewClient->windowCloseRejected(); } +void WebContentsDelegateQt::BeforeUnloadFired(const base::TimeTicks &proceed_time) { + Q_UNUSED(proceed_time); +} + bool WebContentsDelegateQt::CheckMediaAccessPermission(content::WebContents *web_contents, const GURL& security_origin, content::MediaStreamType type) { switch (type) { @@ -556,4 +559,8 @@ FaviconManager *WebContentsDelegateQt::faviconManager() return m_faviconManager.data(); } +WebEngineSettings *WebContentsDelegateQt::webEngineSettings() const { + return m_viewClient->webEngineSettings(); +} + } // namespace QtWebEngineCore diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h index 20c70ef21..2e37c498a 100644 --- a/src/core/web_contents_delegate_qt.h +++ b/src/core/web_contents_delegate_qt.h @@ -68,6 +68,7 @@ namespace content { namespace QtWebEngineCore { class WebContentsAdapterClient; +class WebEngineSettings; class SavePageInfo { @@ -104,7 +105,7 @@ public: void LoadProgressChanged(content::WebContents* source, double progress) override; void HandleKeyboardEvent(content::WebContents *source, const content::NativeWebKeyboardEvent &event) override; content::ColorChooser *OpenColorChooser(content::WebContents *source, SkColor color, const std::vector<content::ColorSuggestion> &suggestion) override; - void WebContentsCreated(content::WebContents* source_contents, int opener_render_process_id, int opener_render_frame_id, const std::string& frame_name, const GURL& target_url, content::WebContents* new_contents) override; + void WebContentsCreated(content::WebContents* source_contents, int opener_render_process_id, int opener_render_frame_id, const std::string& frame_name, const GURL& target_url, content::WebContents* new_contents, const base::Optional<content::WebContents::CreateParams>& create_params) override; content::JavaScriptDialogManager *GetJavaScriptDialogManager(content::WebContents *source) override; void EnterFullscreenModeForTab(content::WebContents* web_contents, const GURL& origin) override; void ExitFullscreenModeForTab(content::WebContents*) override; @@ -131,12 +132,12 @@ public: void DidFailLoad(content::RenderFrameHost *render_frame_host, const GURL &validated_url, int error_code, const base::string16 &error_description, bool was_ignored_by_handler) override; void DidFinishLoad(content::RenderFrameHost *render_frame_host, const GURL &validated_url) override; + void BeforeUnloadFired(const base::TimeTicks& proceed_time) override; void DidUpdateFaviconURL(const std::vector<content::FaviconURL> &candidates) override; void WasShown() override; void DidFirstVisuallyNonEmptyPaint() override; void ActivateContents(content::WebContents* contents) override; - void didFailLoad(const QUrl &url, int errorCode, const QString &errorDescription); void overrideWebPreferences(content::WebContents *, content::WebPreferences*); void allowCertificateError(const QSharedPointer<CertificateErrorController> &) ; @@ -147,6 +148,8 @@ public: void setSavePageInfo(const SavePageInfo &spi) { m_savePageInfo = spi; } const SavePageInfo &savePageInfo() { return m_savePageInfo; } + WebEngineSettings *webEngineSettings() const; + private: QWeakPointer<WebContentsAdapter> createWindow(content::WebContents *new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture); void EmitLoadStarted(const QUrl &url, bool isErrorPage = false); diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp index e627fa06d..28f202e24 100644 --- a/src/core/web_contents_view_qt.cpp +++ b/src/core/web_contents_view_qt.cpp @@ -138,25 +138,25 @@ void WebContentsViewQt::SetInitialFocus() Focus(); } -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeNone, blink::WebContextMenuData::MediaTypeNone) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeImage, blink::WebContextMenuData::MediaTypeImage) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeVideo, blink::WebContextMenuData::MediaTypeVideo) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeAudio, blink::WebContextMenuData::MediaTypeAudio) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeCanvas, blink::WebContextMenuData::MediaTypeCanvas) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeFile, blink::WebContextMenuData::MediaTypeFile) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypePlugin, blink::WebContextMenuData::MediaTypePlugin) - -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaNone, blink::WebContextMenuData::MediaNone) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaInError, blink::WebContextMenuData::MediaInError) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaPaused, blink::WebContextMenuData::MediaPaused) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaMuted, blink::WebContextMenuData::MediaMuted) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaLoop, blink::WebContextMenuData::MediaLoop) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanSave, blink::WebContextMenuData::MediaCanSave) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaHasAudio, blink::WebContextMenuData::MediaHasAudio) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanToggleControls, blink::WebContextMenuData::MediaCanToggleControls) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaControls, blink::WebContextMenuData::MediaControls) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanPrint, blink::WebContextMenuData::MediaCanPrint) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanRotate, blink::WebContextMenuData::MediaCanRotate) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeNone, blink::WebContextMenuData::kMediaTypeNone) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeImage, blink::WebContextMenuData::kMediaTypeImage) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeVideo, blink::WebContextMenuData::kMediaTypeVideo) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeAudio, blink::WebContextMenuData::kMediaTypeAudio) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeCanvas, blink::WebContextMenuData::kMediaTypeCanvas) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeFile, blink::WebContextMenuData::kMediaTypeFile) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypePlugin, blink::WebContextMenuData::kMediaTypePlugin) + +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaNone, blink::WebContextMenuData::kMediaNone) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaInError, blink::WebContextMenuData::kMediaInError) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaPaused, blink::WebContextMenuData::kMediaPaused) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaMuted, blink::WebContextMenuData::kMediaMuted) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaLoop, blink::WebContextMenuData::kMediaLoop) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanSave, blink::WebContextMenuData::kMediaCanSave) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaHasAudio, blink::WebContextMenuData::kMediaHasAudio) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanToggleControls, blink::WebContextMenuData::kMediaCanToggleControls) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaControls, blink::WebContextMenuData::kMediaControls) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanPrint, blink::WebContextMenuData::kMediaCanPrint) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanRotate, blink::WebContextMenuData::kMediaCanRotate) static inline WebEngineContextMenuData fromParams(const content::ContextMenuParams ¶ms) { @@ -176,6 +176,9 @@ static inline WebEngineContextMenuData fromParams(const content::ContextMenuPara ret.setMisspelledWord(toQt(params.misspelled_word)); ret.setSpellCheckerSuggestions(fromVector(params.dictionary_suggestions)); #endif + ret.setFrameUrl(toQt(params.frame_url)); + ret.setPageUrl(toQt(params.page_url)); + ret.setReferrerPolicy((ReferrerPolicy)params.referrer_policy); return ret; } @@ -198,11 +201,11 @@ void WebContentsViewQt::ShowContextMenu(content::RenderFrameHost *, const conten Qt::DropActions toQtDropActions(blink::WebDragOperationsMask ops) { Qt::DropActions result; - if (ops & blink::WebDragOperationCopy) + if (ops & blink::kWebDragOperationCopy) result |= Qt::CopyAction; - if (ops & blink::WebDragOperationLink) + if (ops & blink::kWebDragOperationLink) result |= Qt::LinkAction; - if (ops & blink::WebDragOperationMove || ops & blink::WebDragOperationDelete) + if (ops & blink::kWebDragOperationMove || ops & blink::kWebDragOperationDelete) result |= Qt::MoveAction; return result; } diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 54564718f..2339537aa 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -61,15 +61,17 @@ #include "content/public/browser/browser_main_runner.h" #include "content/public/browser/plugin_service.h" #include "content/public/browser/render_frame_host.h" +#include "content/public/common/content_features.h" #include "content/public/common/content_paths.h" #include "content/public/common/content_switches.h" #include "content/public/common/main_function_params.h" #include "content/renderer/in_process_renderer_thread.h" #include "content/utility/in_process_utility_thread.h" #include "gpu/command_buffer/service/gpu_switches.h" +#include "net/base/port_util.h" #include "ppapi/features/features.h" #include "ui/events/event_switches.h" -#include "ui/native_theme/native_theme_switches.h" +#include "ui/native_theme/native_theme_features.h" #include "ui/gl/gl_switches.h" #if defined(OS_WIN) #include "sandbox/win/src/sandbox_types.h" @@ -133,21 +135,6 @@ bool usingANGLE() #endif } -bool usingSoftwareDynamicGL() -{ - if (QCoreApplication::testAttribute(Qt::AA_UseSoftwareOpenGL)) - return true; -#if defined(Q_OS_WIN) - HMODULE handle = static_cast<HMODULE>(QOpenGLContext::openGLModuleHandle()); - wchar_t path[MAX_PATH]; - DWORD size = GetModuleFileName(handle, path, MAX_PATH); - QFileInfo openGLModule(QString::fromWCharArray(path, size)); - return openGLModule.fileName() == QLatin1String("opengl32sw.dll"); -#else - return false; -#endif -} - bool usingQtQuick2DRenderer() { const QStringList args = QGuiApplication::arguments(); @@ -184,6 +171,21 @@ void dummyGetPluginCallback(const std::vector<content::WebPluginInfo>&) namespace QtWebEngineCore { +bool usingSoftwareDynamicGL() +{ + if (QCoreApplication::testAttribute(Qt::AA_UseSoftwareOpenGL)) + return true; +#if defined(Q_OS_WIN) + HMODULE handle = static_cast<HMODULE>(QOpenGLContext::openGLModuleHandle()); + wchar_t path[MAX_PATH]; + DWORD size = GetModuleFileName(handle, path, MAX_PATH); + QFileInfo openGLModule(QString::fromWCharArray(path, size)); + return openGLModule.fileName() == QLatin1String("opengl32sw.dll"); +#else + return false; +#endif +} + void WebEngineContext::destroyBrowserContext() { m_defaultBrowserContext.reset(); @@ -195,7 +197,8 @@ void WebEngineContext::destroy() m_devtoolsServer->stop(); delete m_globalQObject; m_globalQObject = 0; - base::MessagePump::Delegate *delegate = m_runLoop->loop_; + base::MessagePump::Delegate *delegate = + static_cast<base::MessageLoop *>(m_runLoop->delegate_); // Flush the UI message loop before quitting. while (delegate->DoWork()) { } GLContextHelper::destroy(); @@ -284,6 +287,11 @@ WebEngineContext::WebEngineContext() appArgs.append(QString::fromLocal8Bit(qgetenv(kChromiumFlagsEnv)).split(' ')); } +#ifdef Q_OS_WIN + bool enableWebGLSoftwareRendering = + appArgs.removeAll(QStringLiteral("--enable-webgl-software-rendering")); +#endif + bool useEmbeddedSwitches = false; #if defined(QTWEBENGINE_EMBEDDED_SWITCHES) useEmbeddedSwitches = !appArgs.removeAll(QStringLiteral("--disable-embedded-switches")); @@ -317,7 +325,6 @@ WebEngineContext::WebEngineContext() } parsedCommandLine->AppendSwitch(switches::kEnableThreadedCompositing); - parsedCommandLine->AppendSwitch(switches::kInProcessGPU); // These are currently only default on OS X, and we don't support them: parsedCommandLine->AppendSwitch(switches::kDisableZeroCopy); parsedCommandLine->AppendSwitch(switches::kDisableGpuMemoryBufferCompositorResources); @@ -344,10 +351,15 @@ WebEngineContext::WebEngineContext() parsedCommandLine->AppendSwitch(switches::kDisableES3GLContext); #endif + // Needed to allow navigations within pages that were set using setHtml(). One example is + // tst_QWebEnginePage::acceptNavigationRequest. + // This is deprecated behavior, and will be removed in a future Chromium version, as per + // upstream Chromium commit ba52f56207a4b9d70b34880fbff2352e71a06422. + parsedCommandLine->AppendSwitchASCII(switches::kEnableFeatures, + features::kAllowContentInitiatedDataUrlNavigations.name); + if (useEmbeddedSwitches) { - // Inspired by the Android port's default switches - if (!parsedCommandLine->HasSwitch(switches::kDisableOverlayScrollbar)) - parsedCommandLine->AppendSwitch(switches::kEnableOverlayScrollbar); + parsedCommandLine->AppendSwitchASCII(switches::kEnableFeatures, features::kOverlayScrollbar.name); if (!parsedCommandLine->HasSwitch(switches::kDisablePinch)) parsedCommandLine->AppendSwitch(switches::kEnablePinch); parsedCommandLine->AppendSwitch(switches::kEnableViewport); @@ -363,7 +375,20 @@ WebEngineContext::WebEngineContext() const char *glType = 0; #ifndef QT_NO_OPENGL - if (!usingANGLE() && !usingSoftwareDynamicGL() && !usingQtQuick2DRenderer()) { + + bool tryGL = + !usingANGLE() + && (!usingSoftwareDynamicGL() +#ifdef Q_OS_WIN + // If user requested WebGL support on Windows, instead of using Skia rendering to + // bitmaps, use software rendering via opengl32sw.dll. This might be less + // performant, but at least provides WebGL support. + || enableWebGLSoftwareRendering +#endif + ) + && !usingQtQuick2DRenderer(); + + if (tryGL) { if (qt_gl_global_share_context() && qt_gl_global_share_context()->isValid()) { // If the native handle is QEGLNativeContext try to use GL ES/2, if there is no native handle // assume we are using wayland and try GL ES/2, and finally Ozone demands GL ES/2 too. @@ -409,8 +434,7 @@ WebEngineContext::WebEngineContext() QSurfaceFormat globalSharedFormat = qt_gl_global_share_context()->format(); if (globalSharedFormat.profile() == QSurfaceFormat::CoreProfile) { #ifdef Q_OS_MACOS - // @TODO_FIXME_ADAPT_QT - // glType = gl::kGLImplementationCoreProfileName; + glType = gl::kGLImplementationCoreProfileName; #else qWarning("An OpenGL Core Profile was requested, but it is not supported " "on the current platform. Falling back to a non-Core profile. " @@ -428,17 +452,24 @@ WebEngineContext::WebEngineContext() } #endif - if (glType) + if (glType) { parsedCommandLine->AppendSwitchASCII(switches::kUseGL, glType); - else + parsedCommandLine->AppendSwitch(switches::kInProcessGPU); +#ifdef Q_OS_WIN + if (enableWebGLSoftwareRendering) + parsedCommandLine->AppendSwitch(switches::kDisableGpuRasterization); +#endif + } else { parsedCommandLine->AppendSwitch(switches::kDisableGpu); + } content::UtilityProcessHostImpl::RegisterUtilityMainThreadFactory(content::CreateInProcessUtilityThread); content::RenderProcessHostImpl::RegisterRendererMainThreadFactory(content::CreateInProcessRendererThread); content::RegisterGpuMainThreadFactory(content::CreateInProcessGpuThread); + mojo::edk::Init(); + content::ContentMainParams contentMainParams(m_mainDelegate.get()); - contentMainParams.setup_signal_handlers = false; #if defined(OS_WIN) sandbox::SandboxInterfaceInfo sandbox_info = {0}; content::InitializeSandboxInfo(&sandbox_info); @@ -460,6 +491,11 @@ WebEngineContext::WebEngineContext() base::ThreadRestrictions::SetIOAllowed(true); + if (parsedCommandLine->HasSwitch(switches::kExplicitlyAllowedPorts)) { + std::string allowedPorts = parsedCommandLine->GetSwitchValueASCII(switches::kExplicitlyAllowedPorts); + net::SetExplicitlyAllowedPorts(allowedPorts); + } + #if BUILDFLAG(ENABLE_PLUGINS) // Creating pepper plugins from the page (which calls PluginService::GetPluginInfoArray) // might fail unless the page queried the list of available plugins at least once diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h index 386f43035..92c45e260 100644 --- a/src/core/web_engine_context.h +++ b/src/core/web_engine_context.h @@ -74,6 +74,8 @@ class ContentMainDelegateQt; class DevToolsServerQt; class SurfaceFactoryQt; +bool usingSoftwareDynamicGL(); + class WebEngineContext : public base::RefCounted<WebEngineContext> { public: static scoped_refptr<WebEngineContext> current(); diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp index 31d120899..4c944892a 100644 --- a/src/core/web_engine_settings.cpp +++ b/src/core/web_engine_settings.cpp @@ -83,21 +83,6 @@ private: WebEngineSettings *m_settings; }; -static inline bool isTouchScreenAvailable() { - static bool initialized = false; - static bool touchScreenAvailable = false; - if (!initialized) { - Q_FOREACH (const QTouchDevice *d, QTouchDevice::devices()) { - if (d->type() == QTouchDevice::TouchScreen) { - touchScreenAvailable = true; - break; - } - } - initialized = true; - } - return touchScreenAvailable; -} - static inline bool isTouchEventsAPIEnabled() { static bool initialized = false; static bool touchEventsAPIEnabled = false; @@ -114,14 +99,13 @@ static inline bool isTouchEventsAPIEnabled() { if (touchEventsSwitchValue == switches::kTouchEventFeatureDetectionEnabled) touchEventsAPIEnabled = true; else if (touchEventsSwitchValue == switches::kTouchEventFeatureDetectionAuto) - touchEventsAPIEnabled = isTouchScreenAvailable(); + touchEventsAPIEnabled = (ui::GetTouchScreensAvailability() == ui::TouchScreensAvailability::ENABLED); initialized = true; } return touchEventsAPIEnabled; } - WebEngineSettings::WebEngineSettings(WebEngineSettings *_parentSettings) : m_adapter(0) , m_batchTimer(new BatchTimer(this)) @@ -264,7 +248,7 @@ void WebEngineSettings::initDefaults() s_defaultAttributes.insert(Accelerated2dCanvasEnabled, accelerated2dCanvas); s_defaultAttributes.insert(AutoLoadIconsForPage, true); s_defaultAttributes.insert(TouchIconsEnabled, false); - s_defaultAttributes.insert(FocusOnNavigationEnabled, true); + s_defaultAttributes.insert(FocusOnNavigationEnabled, false); s_defaultAttributes.insert(PrintElementBackgrounds, true); s_defaultAttributes.insert(AllowRunningInsecureContent, allowRunningInsecureContent); s_defaultAttributes.insert(AllowGeolocationOnInsecureOrigins, false); @@ -323,7 +307,6 @@ void WebEngineSettings::applySettingsToWebPreferences(content::WebPreferences *p { // Override for now prefs->touch_event_feature_detection_enabled = isTouchEventsAPIEnabled(); - prefs->device_supports_touch = isTouchScreenAvailable(); if (prefs->viewport_enabled) { // We should enable viewport and viewport-meta together, but since 5.7 we // no longer have a command-line flag for viewport-meta. @@ -333,7 +316,6 @@ void WebEngineSettings::applySettingsToWebPreferences(content::WebPreferences *p // Attributes mapping. prefs->loads_images_automatically = testAttribute(AutoLoadImages); prefs->javascript_enabled = testAttribute(JavascriptEnabled); - prefs->javascript_can_open_windows_automatically = testAttribute(JavascriptCanOpenWindows); prefs->javascript_can_access_clipboard = testAttribute(JavascriptCanAccessClipboard); prefs->tabs_to_links = testAttribute(LinksIncludedInFocusChain); prefs->local_storage_enabled = testAttribute(LocalStorageEnabled); @@ -377,6 +359,11 @@ void WebEngineSettings::scheduleApplyRecursively() } } +bool WebEngineSettings::getJavaScriptCanOpenWindowsAutomatically() +{ + return testAttribute(JavascriptCanOpenWindows); +} + void WebEngineSettings::setParentSettings(WebEngineSettings *_parentSettings) { if (parentSettings) diff --git a/src/core/web_engine_settings.h b/src/core/web_engine_settings.h index 1304d2ae9..639d314f3 100644 --- a/src/core/web_engine_settings.h +++ b/src/core/web_engine_settings.h @@ -134,6 +134,8 @@ public: void scheduleApplyRecursively(); + bool getJavaScriptCanOpenWindowsAutomatically(); + private: void doApply(); void applySettingsToWebPreferences(content::WebPreferences *); diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp index 7f164d6bd..18f8d393f 100644 --- a/src/core/web_event_factory.cpp +++ b/src/core/web_event_factory.cpp @@ -144,7 +144,6 @@ static int windowsKeyCodeForKeyEvent(unsigned int keycode, bool isKeypad) return VK_SHIFT; // (10) SHIFT key case Qt::Key_Control: return VK_CONTROL; // (11) CTRL key - case Qt::Key_Menu: case Qt::Key_Alt: return VK_MENU; // (12) ALT key default: @@ -167,7 +166,6 @@ static int windowsKeyCodeForKeyEvent(unsigned int keycode, bool isKeypad) return VK_SHIFT; // (10) SHIFT key case Qt::Key_Control: return VK_CONTROL; // (11) CTRL key - case Qt::Key_Menu: case Qt::Key_Alt: return VK_MENU; // (12) ALT key @@ -357,7 +355,8 @@ static int windowsKeyCodeForKeyEvent(unsigned int keycode, bool isKeypad) return VK_LWIN; // (5B) Left Windows key (Microsoft Natural keyboard) // case Qt::Key_Meta_R: FIXME: What to do here? // return VK_RWIN; // (5C) Right Windows key (Natural keyboard) - // VK_APPS (5D) Applications key (Natural keyboard) + case Qt::Key_Menu: // (5D) Applications key (Natural keyboard) + return VK_APPS; // VK_SLEEP (5F) Computer Sleep key // VK_SEPARATOR (6C) Separator key // VK_SUBTRACT (6D) Subtract key @@ -1036,25 +1035,25 @@ static inline double currentTimeForEvent(const QInputEvent* event) static WebMouseEvent::Button mouseButtonForEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) - return WebMouseEvent::Button::Left; + return WebMouseEvent::Button::kLeft; else if (event->button() == Qt::RightButton) - return WebMouseEvent::Button::Right; + return WebMouseEvent::Button::kRight; else if (event->button() == Qt::MidButton) - return WebMouseEvent::Button::Middle; + return WebMouseEvent::Button::kMiddle; if (event->type() != QEvent::MouseMove) - return WebMouseEvent::Button::NoButton; + return WebMouseEvent::Button::kNoButton; // This is technically wrong, mouse move should always have ButtonNone, // but it is consistent with aura and selection code depends on it: if (event->buttons() & Qt::LeftButton) - return WebMouseEvent::Button::Left; + return WebMouseEvent::Button::kLeft; else if (event->buttons() & Qt::RightButton) - return WebMouseEvent::Button::Right; + return WebMouseEvent::Button::kRight; else if (event->buttons() & Qt::MidButton) - return WebMouseEvent::Button::Middle; + return WebMouseEvent::Button::kMiddle; - return WebMouseEvent::Button::NoButton; + return WebMouseEvent::Button::kNoButton; } template <typename T> @@ -1062,11 +1061,11 @@ static unsigned mouseButtonsModifiersForEvent(const T* event) { unsigned ret = 0; if (event->buttons() & Qt::LeftButton) - ret |= WebInputEvent::LeftButtonDown; + ret |= WebInputEvent::kLeftButtonDown; if (event->buttons() & Qt::RightButton) - ret |= WebInputEvent::RightButtonDown; + ret |= WebInputEvent::kRightButtonDown; if (event->buttons() & Qt::MidButton) - ret |= WebInputEvent::MiddleButtonDown; + ret |= WebInputEvent::kMiddleButtonDown; return ret; } @@ -1076,19 +1075,19 @@ static inline WebInputEvent::Modifiers modifierForKeyCode(int key) { switch (key) { case Qt::Key_Shift: - return WebInputEvent::ShiftKey; + return WebInputEvent::kShiftKey; case Qt::Key_Alt: - return WebInputEvent::AltKey; + return WebInputEvent::kAltKey; #if defined(Q_OS_OSX) case Qt::Key_Control: - return (!qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) ? WebInputEvent::MetaKey : WebInputEvent::ControlKey; + return (!qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) ? WebInputEvent::kMetaKey : WebInputEvent::kControlKey; case Qt::Key_Meta: - return (!qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) ? WebInputEvent::ControlKey : WebInputEvent::MetaKey; + return (!qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) ? WebInputEvent::kControlKey : WebInputEvent::kMetaKey; #else case Qt::Key_Control: - return WebInputEvent::ControlKey; + return WebInputEvent::kControlKey; case Qt::Key_Meta: - return WebInputEvent::MetaKey; + return WebInputEvent::kMetaKey; #endif default: return static_cast<WebInputEvent::Modifiers>(0); @@ -1102,24 +1101,24 @@ static inline WebInputEvent::Modifiers modifiersForEvent(const QInputEvent* even #if defined(Q_OS_OSX) if (!qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { if (modifiers & Qt::ControlModifier) - result |= WebInputEvent::MetaKey; + result |= WebInputEvent::kMetaKey; if (modifiers & Qt::MetaModifier) - result |= WebInputEvent::ControlKey; + result |= WebInputEvent::kControlKey; } else #endif { if (modifiers & Qt::ControlModifier) - result |= WebInputEvent::ControlKey; + result |= WebInputEvent::kControlKey; if (modifiers & Qt::MetaModifier) - result |= WebInputEvent::MetaKey; + result |= WebInputEvent::kMetaKey; } if (modifiers & Qt::ShiftModifier) - result |= WebInputEvent::ShiftKey; + result |= WebInputEvent::kShiftKey; if (modifiers & Qt::AltModifier) - result |= WebInputEvent::AltKey; + result |= WebInputEvent::kAltKey; if (modifiers & Qt::KeypadModifier) - result |= WebInputEvent::IsKeyPad; + result |= WebInputEvent::kIsKeyPad; switch (event->type()) { case QEvent::MouseButtonPress: @@ -1134,7 +1133,7 @@ static inline WebInputEvent::Modifiers modifiersForEvent(const QInputEvent* even case QEvent::KeyRelease: { const QKeyEvent *keyEvent = static_cast<const QKeyEvent*>(event); if (keyEvent->isAutoRepeat()) - result |= WebInputEvent::IsAutoRepeat; + result |= WebInputEvent::kIsAutoRepeat; result |= modifierForKeyCode(keyEvent->key()); } default: @@ -1148,52 +1147,49 @@ static WebInputEvent::Type webEventTypeForEvent(const QEvent* event) { switch (event->type()) { case QEvent::MouseButtonPress: - return WebInputEvent::MouseDown; + return WebInputEvent::kMouseDown; case QEvent::MouseButtonRelease: - return WebInputEvent::MouseUp; + return WebInputEvent::kMouseUp; case QEvent::Enter: - return WebInputEvent::MouseEnter; + return WebInputEvent::kMouseEnter; case QEvent::Leave: - return WebInputEvent::MouseLeave; + return WebInputEvent::kMouseLeave; case QEvent::MouseMove: - return WebInputEvent::MouseMove; + return WebInputEvent::kMouseMove; case QEvent::Wheel: - return WebInputEvent::MouseWheel; + return WebInputEvent::kMouseWheel; case QEvent::KeyPress: - return WebInputEvent::RawKeyDown; + return WebInputEvent::kRawKeyDown; case QEvent::KeyRelease: - return WebInputEvent::KeyUp; + return WebInputEvent::kKeyUp; case QEvent::HoverMove: - return WebInputEvent::MouseMove; + return WebInputEvent::kMouseMove; case QEvent::TouchBegin: - return WebInputEvent::TouchStart; + return WebInputEvent::kTouchStart; case QEvent::TouchUpdate: - return WebInputEvent::TouchMove; + return WebInputEvent::kTouchMove; case QEvent::TouchEnd: - return WebInputEvent::TouchEnd; + return WebInputEvent::kTouchEnd; case QEvent::TouchCancel: - return WebInputEvent::TouchCancel; + return WebInputEvent::kTouchCancel; default: Q_ASSERT(false); - return WebInputEvent::MouseMove; + return WebInputEvent::kMouseMove; } } WebMouseEvent WebEventFactory::toWebMouseEvent(QMouseEvent *ev, double dpiScale) { - WebMouseEvent webKitEvent; - webKitEvent.setTimeStampSeconds(currentTimeForEvent(ev)); - webKitEvent.setModifiers(modifiersForEvent(ev)); - webKitEvent.setType(webEventTypeForEvent(ev)); + WebMouseEvent webKitEvent(webEventTypeForEvent(ev), + ev->x() / dpiScale, + ev->y() / dpiScale, + ev->globalX(), + ev->globalY(), + modifiersForEvent(ev), + currentTimeForEvent(ev)); webKitEvent.button = mouseButtonForEvent(ev); - - webKitEvent.x = webKitEvent.windowX = ev->x() / dpiScale; - webKitEvent.y = webKitEvent.windowY = ev->y() / dpiScale; - webKitEvent.globalX = ev->globalX(); - webKitEvent.globalY = ev->globalY(); - - webKitEvent.clickCount = 0; + webKitEvent.click_count = 0; return webKitEvent; } @@ -1201,41 +1197,41 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QMouseEvent *ev, double dpiScale) WebMouseEvent WebEventFactory::toWebMouseEvent(QHoverEvent *ev, double dpiScale) { WebMouseEvent webKitEvent; - webKitEvent.setTimeStampSeconds(currentTimeForEvent(ev)); - webKitEvent.setModifiers(modifiersForEvent(ev)); - webKitEvent.setType(webEventTypeForEvent(ev)); + webKitEvent.SetTimeStampSeconds(currentTimeForEvent(ev)); + webKitEvent.SetModifiers(modifiersForEvent(ev)); + webKitEvent.SetType(webEventTypeForEvent(ev)); - webKitEvent.x = webKitEvent.windowX = ev->pos().x() / dpiScale; - webKitEvent.y = webKitEvent.windowY = ev->pos().y() / dpiScale; - webKitEvent.movementX = ev->pos().x() - ev->oldPos().x(); - webKitEvent.movementY = ev->pos().y() - ev->oldPos().y(); + webKitEvent.SetPositionInWidget(ev->pos().x() / dpiScale, ev->pos().y() / dpiScale); + webKitEvent.movement_x = ev->pos().x() - ev->oldPos().x(); + webKitEvent.movement_y = ev->pos().y() - ev->oldPos().y(); return webKitEvent; } +#ifndef QT_NO_GESTURES WebGestureEvent WebEventFactory::toWebGestureEvent(QNativeGestureEvent *ev, double dpiScale) { WebGestureEvent webKitEvent; - webKitEvent.setTimeStampSeconds(currentTimeForEvent(ev)); - webKitEvent.setModifiers(modifiersForEvent(ev)); + webKitEvent.SetTimeStampSeconds(currentTimeForEvent(ev)); + webKitEvent.SetModifiers(modifiersForEvent(ev)); webKitEvent.x = static_cast<int>(ev->localPos().x() / dpiScale); webKitEvent.y = static_cast<int>(ev->localPos().y() / dpiScale); - webKitEvent.globalX = static_cast<int>(ev->screenPos().x() / dpiScale); - webKitEvent.globalY = static_cast<int>(ev->screenPos().y() / dpiScale); + webKitEvent.global_x = static_cast<int>(ev->screenPos().x() / dpiScale); + webKitEvent.global_y = static_cast<int>(ev->screenPos().y() / dpiScale); - webKitEvent.sourceDevice = blink::WebGestureDeviceTouchpad; + webKitEvent.source_device = blink::kWebGestureDeviceTouchpad; Qt::NativeGestureType gestureType = ev->gestureType(); switch (gestureType) { case Qt::ZoomNativeGesture: - webKitEvent.setType(WebInputEvent::GesturePinchUpdate); - webKitEvent.data.pinchUpdate.scale = static_cast<float>(ev->value() + 1.0); + webKitEvent.SetType(WebInputEvent::kGesturePinchUpdate); + webKitEvent.data.pinch_update.scale = static_cast<float>(ev->value() + 1.0); break; case Qt::SmartZoomNativeGesture: - webKitEvent.setType(WebInputEvent::GestureDoubleTap); - webKitEvent.data.tap.tapCount = 1; + webKitEvent.SetType(WebInputEvent::kGestureDoubleTap); + webKitEvent.data.tap.tap_count = 1; break; case Qt::BeginNativeGesture: case Qt::EndNativeGesture: @@ -1243,26 +1239,27 @@ WebGestureEvent WebEventFactory::toWebGestureEvent(QNativeGestureEvent *ev, doub case Qt::PanNativeGesture: case Qt::SwipeNativeGesture: // Not implemented by Chromium for now. - webKitEvent.setType(blink::WebInputEvent::Undefined); + webKitEvent.SetType(blink::WebInputEvent::kUndefined); break; } return webKitEvent; } +#endif blink::WebMouseWheelEvent WebEventFactory::toWebWheelEvent(QWheelEvent *ev, double dpiScale) { WebMouseWheelEvent webEvent; - webEvent.deltaX = 0; - webEvent.deltaY = 0; - webEvent.wheelTicksX = 0; - webEvent.wheelTicksY = 0; - webEvent.setType(webEventTypeForEvent(ev)); - webEvent.setModifiers(modifiersForEvent(ev)); - webEvent.setTimeStampSeconds(currentTimeForEvent(ev)); + webEvent.delta_x = 0; + webEvent.delta_y = 0; + webEvent.wheel_ticks_x = 0; + webEvent.wheel_ticks_y = 0; + webEvent.SetType(webEventTypeForEvent(ev)); + webEvent.SetModifiers(modifiersForEvent(ev)); + webEvent.SetTimeStampSeconds(currentTimeForEvent(ev)); - webEvent.wheelTicksX = static_cast<float>(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep; - webEvent.wheelTicksY = static_cast<float>(ev->angleDelta().y()) / QWheelEvent::DefaultDeltasPerStep; + webEvent.wheel_ticks_x = static_cast<float>(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep; + webEvent.wheel_ticks_y = static_cast<float>(ev->angleDelta().y()) / QWheelEvent::DefaultDeltasPerStep; // We can't use the device specific QWheelEvent::pixelDelta(), so we calculate // a pixel delta based on ticks and scroll per line. @@ -1273,43 +1270,42 @@ blink::WebMouseWheelEvent WebEventFactory::toWebWheelEvent(QWheelEvent *ev, doub #else const int wheelScrollLines = 3; #endif - webEvent.deltaX = webEvent.wheelTicksX * wheelScrollLines * cDefaultQtScrollStep; - webEvent.deltaY = webEvent.wheelTicksY * wheelScrollLines * cDefaultQtScrollStep; + webEvent.delta_x = webEvent.wheel_ticks_x * wheelScrollLines * cDefaultQtScrollStep; + webEvent.delta_y = webEvent.wheel_ticks_y * wheelScrollLines * cDefaultQtScrollStep; + + webEvent.SetPositionInWidget(ev->x() / dpiScale, ev->y() / dpiScale); + webEvent.SetPositionInScreen(ev->globalX(), ev->globalY()); - webEvent.x = webEvent.windowX = ev->x() / dpiScale; - webEvent.y = webEvent.windowY = ev->y() / dpiScale; - webEvent.globalX = ev->globalX(); - webEvent.globalY = ev->globalY(); return webEvent; } content::NativeWebKeyboardEvent WebEventFactory::toWebKeyboardEvent(QKeyEvent *ev) { content::NativeWebKeyboardEvent webKitEvent(reinterpret_cast<gfx::NativeEvent>(ev)); - webKitEvent.setTimeStampSeconds(currentTimeForEvent(ev)); - webKitEvent.setModifiers(modifiersForEvent(ev)); - webKitEvent.setType(webEventTypeForEvent(ev)); + webKitEvent.SetTimeStampSeconds(currentTimeForEvent(ev)); + webKitEvent.SetModifiers(modifiersForEvent(ev)); + webKitEvent.SetType(webEventTypeForEvent(ev)); - webKitEvent.nativeKeyCode = ev->nativeVirtualKey(); - webKitEvent.windowsKeyCode = windowsKeyCodeForKeyEvent(ev->key(), ev->modifiers() & Qt::KeypadModifier); - webKitEvent.domKey = getDomKeyFromQKeyEvent(ev); + webKitEvent.native_key_code = ev->nativeVirtualKey(); + webKitEvent.windows_key_code = windowsKeyCodeForKeyEvent(ev->key(), ev->modifiers() & Qt::KeypadModifier); + webKitEvent.dom_key = getDomKeyFromQKeyEvent(ev); ui::DomCode domCode = ui::DomCode::NONE; int scanCode = ev->nativeScanCode(); if (scanCode) domCode = ui::KeycodeConverter::NativeKeycodeToDomCode(scanCode); - webKitEvent.domCode = static_cast<int>(domCode); + webKitEvent.dom_code = static_cast<int>(domCode); const ushort* text = ev->text().utf16(); memcpy(&webKitEvent.text, text, std::min(sizeof(webKitEvent.text), size_t(ev->text().length() * 2))); - memcpy(&webKitEvent.unmodifiedText, text, std::min(sizeof(webKitEvent.unmodifiedText), size_t(ev->text().length() * 2))); + memcpy(&webKitEvent.unmodified_text, text, std::min(sizeof(webKitEvent.unmodified_text), size_t(ev->text().length() * 2))); - if (webKitEvent.windowsKeyCode == VK_RETURN) { + if (webKitEvent.windows_key_code == VK_RETURN) { // This is the same behavior as GTK: // We need to treat the enter key as a key press of character \r. This // is apparently just how webkit handles it and what it expects. - webKitEvent.unmodifiedText[0] = '\r'; - webKitEvent.text[0] = webKitEvent.unmodifiedText[0]; + webKitEvent.unmodified_text[0] = '\r'; + webKitEvent.text[0] = webKitEvent.unmodified_text[0]; } return webKitEvent; diff --git a/src/core/web_event_factory.h b/src/core/web_event_factory.h index b5e465610..259795c1f 100644 --- a/src/core/web_event_factory.h +++ b/src/core/web_event_factory.h @@ -41,7 +41,9 @@ #define WEB_EVENT_FACTORY_H #include "content/public/browser/native_web_keyboard_event.h" +#ifndef QT_NO_GESTURES #include "third_party/WebKit/public/platform/WebGestureEvent.h" +#endif #include "third_party/WebKit/public/platform/WebMouseEvent.h" #include "third_party/WebKit/public/platform/WebMouseWheelEvent.h" @@ -52,7 +54,9 @@ class QHoverEvent; class QKeyEvent; class QMouseEvent; class QWheelEvent; +#ifndef QT_NO_GESTURES class QNativeGestureEvent; +#endif QT_END_NAMESPACE class WebEventFactory { @@ -60,7 +64,9 @@ class WebEventFactory { public: static blink::WebMouseEvent toWebMouseEvent(QMouseEvent*, double dpiScale); static blink::WebMouseEvent toWebMouseEvent(QHoverEvent*, double dpiScale); +#ifndef QT_NO_GESTURES static blink::WebGestureEvent toWebGestureEvent(QNativeGestureEvent *, double dpiScale); +#endif static blink::WebMouseWheelEvent toWebWheelEvent(QWheelEvent*, double dpiScale); static content::NativeWebKeyboardEvent toWebKeyboardEvent(QKeyEvent*); }; diff --git a/src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro b/src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro index 4e2c8c847..55b78c696 100644 --- a/src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro +++ b/src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro @@ -41,6 +41,8 @@ INCLUDEPATH += $$CHROMIUM_SRC_DIR SOURCES += \ main.cpp +QMAKE_TARGET_DESCRIPTION = "Qt WebEngine Dictionary Converter" + # Support converting dictionaries in a prefix build, by supplying # the path to the ICU data file located in the Qt build path, rather # than the install path (which is not present at build time). diff --git a/src/webengine/api/qquickwebenginesettings.cpp b/src/webengine/api/qquickwebenginesettings.cpp index 98a3eef39..12d313783 100644 --- a/src/webengine/api/qquickwebenginesettings.cpp +++ b/src/webengine/api/qquickwebenginesettings.cpp @@ -311,8 +311,7 @@ bool QQuickWebEngineSettings::touchIconsEnabled() const Focus is given to the view whenever a navigation operation occurs (load, stop, reload, reload and bypass cache, forward, backward, set content, and so on). - Enabled by default. See \l{WebEngine Recipe Browser} for an example where - this property is disabled. + Disabled by default. */ bool QQuickWebEngineSettings::focusOnNavigationEnabled() const { diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index f8fcb5793..c100c1f20 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -1647,7 +1647,8 @@ void QQuickWebEngineView::triggerWebAction(WebAction action) break; case DownloadLinkToDisk: if (d->m_contextMenuData.linkUrl().isValid()) - d->adapter->download(d->m_contextMenuData.linkUrl(), d->m_contextMenuData.suggestedFileName()); + d->adapter->download(d->m_contextMenuData.linkUrl(), d->m_contextMenuData.suggestedFileName(), + d->m_contextMenuData.referrerUrl(), d->m_contextMenuData.referrerPolicy()); break; case CopyImageToClipboard: if (d->m_contextMenuData.hasImageContent() && @@ -1674,7 +1675,8 @@ void QQuickWebEngineView::triggerWebAction(WebAction action) case DownloadImageToDisk: case DownloadMediaToDisk: if (d->m_contextMenuData.mediaUrl().isValid()) - d->adapter->download(d->m_contextMenuData.mediaUrl(), d->m_contextMenuData.suggestedFileName()); + d->adapter->download(d->m_contextMenuData.mediaUrl(), d->m_contextMenuData.suggestedFileName(), + d->m_contextMenuData.referrerUrl(), d->m_contextMenuData.referrerPolicy()); break; case CopyMediaUrlToClipboard: if (d->m_contextMenuData.mediaUrl().isValid() && diff --git a/src/webengine/doc/src/qtwebengine-features.qdoc b/src/webengine/doc/src/qtwebengine-features.qdoc index 7850ff35d..545d230ef 100644 --- a/src/webengine/doc/src/qtwebengine-features.qdoc +++ b/src/webengine/doc/src/qtwebengine-features.qdoc @@ -55,10 +55,10 @@ Qt WebEngine supports the MPEG-4 Part 14 (MP4) file format only if the required proprietary audio and video codecs, such as H.264 and MPEG layer-3 (MP3), have been enabled. Proprietary codecs can be enabled by passing the - following option to qmake when building Qt WebEngine: + following option when configuring Qt: \code - qmake WEBENGINE_CONFIG+=use_proprietary_codecs + -proprietary-codecs \endcode \warning When distributing proprietary codec libraries, you must acquire diff --git a/src/webengine/doc/src/webengineview.qdoc b/src/webengine/doc/src/webengineview.qdoc index fead1b443..4f0c40e0d 100644 --- a/src/webengine/doc/src/webengineview.qdoc +++ b/src/webengine/doc/src/webengineview.qdoc @@ -86,7 +86,7 @@ focus on press. This can be useful in a hybrid UI. The \l {WebEngineSettings::focusOnNavigationEnabled} {focusOnNavigationEnabled} setting can be - used to stop the view from automatically receiving focus when a navigation operation occurs + used to make the view automatically receive focus when a navigation operation occurs (like loading or reloading a page or navigating through history). The \l linkHovered() signal is emitted when a mouse pointer passes over a link and thus 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 650a40988..047737254 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp +++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp @@ -226,8 +226,10 @@ bool RenderWidgetHostViewQtDelegateQuick::event(QEvent *event) if (event->type() == QEvent::ShortcutOverride) return m_client->handleShortcutOverrideEvent(static_cast<QKeyEvent *>(event)); +#ifndef QT_NO_GESTURES if (event->type() == QEvent::NativeGesture) return m_client->forwardEvent(event); +#endif return QQuickItem::event(event); } diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 41034e43c..a6ff4583f 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -1294,7 +1294,9 @@ void QWebEnginePage::triggerAction(WebAction action, bool) break; case DownloadLinkToDisk: if (menuData.linkUrl().isValid()) - d->adapter->download(menuData.linkUrl(), menuData.suggestedFileName()); + d->adapter->download(menuData.linkUrl(), menuData.suggestedFileName(), + menuData.referrerUrl(), menuData.referrerPolicy()); + break; case CopyImageToClipboard: if (menuData.hasImageContent() && @@ -1321,7 +1323,8 @@ void QWebEnginePage::triggerAction(WebAction action, bool) case DownloadImageToDisk: case DownloadMediaToDisk: if (menuData.mediaUrl().isValid()) - d->adapter->download(menuData.mediaUrl(), menuData.suggestedFileName()); + d->adapter->download(menuData.mediaUrl(), menuData.suggestedFileName(), + menuData.referrerUrl(), menuData.referrerPolicy()); break; case CopyMediaUrlToClipboard: if (menuData.mediaUrl().isValid() && @@ -1485,7 +1488,7 @@ void QWebEnginePagePrivate::wasHidden() bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData &data) { - if (!view || !view->d_func()->m_pendingContextMenuEvent) + if (!view) return false; contextData.reset(); @@ -1511,7 +1514,6 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData event.ignore(); return false; } - view->d_func()->m_pendingContextMenuEvent = false; return true; } diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp index 56948bb18..0037f7e50 100644 --- a/src/webenginewidgets/api/qwebengineview.cpp +++ b/src/webenginewidgets/api/qwebengineview.cpp @@ -106,7 +106,6 @@ static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *obje QWebEngineViewPrivate::QWebEngineViewPrivate() : page(0) - , m_pendingContextMenuEvent(false) , m_dragEntered(false) { #ifndef QT_NO_ACCESSIBILITY @@ -316,12 +315,10 @@ void QWebEngineView::setZoomFactor(qreal factor) */ bool QWebEngineView::event(QEvent *ev) { - Q_D(QWebEngineView); // We swallow spontaneous contextMenu events and synthethize those back later on when we get the // HandleContextMenu callback from chromium if (ev->type() == QEvent::ContextMenu) { ev->accept(); - d->m_pendingContextMenuEvent = true; return true; } return QWidget::event(ev); diff --git a/src/webenginewidgets/api/qwebengineview_p.h b/src/webenginewidgets/api/qwebengineview_p.h index 45b3e266e..f3a37225b 100644 --- a/src/webenginewidgets/api/qwebengineview_p.h +++ b/src/webenginewidgets/api/qwebengineview_p.h @@ -70,7 +70,6 @@ public: QWebEngineViewPrivate(); QWebEnginePage *page; - bool m_pendingContextMenuEvent; bool m_dragEntered; }; diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc index 3b9300a4b..5248a383a 100644 --- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc @@ -89,8 +89,8 @@ \c MainWorld. The \l {QWebEngineSettings::FocusOnNavigationEnabled} {FocusOnNavigationEnabled} setting can be - used to stop the view associated with the page from automatically receiving focus when a - navigation operation occurs (like loading or reloading a page or navigating through history). + used to make the view associated with the page automatically receive focus when a navigation + operation occurs (like loading or reloading a page or navigating through history). */ /*! diff --git a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc index 907f6f643..e6a94281e 100644 --- a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc @@ -148,7 +148,7 @@ Gives focus to the view associated with the page, whenever a navigation operation occurs (load, stop, reload, reload and bypass cache, forward, backward, set content, and so on). - Enabled by default. (Added in Qt 5.8) + Disabled by default. (Added in Qt 5.8) \value PrintElementBackgrounds Turns on printing of CSS backgrounds when printing a web page. Enabled by default. (Added in Qt 5.8) 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 a504506a0..4de425c5b 100644 --- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp +++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp @@ -136,9 +136,25 @@ RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(Rende // Make sure the OpenGL profile of the QQuickWidget matches the shared context profile. if (sharedFormat.profile() == QSurfaceFormat::CoreProfile) { - format.setMajorVersion(sharedFormat.majorVersion()); - format.setMinorVersion(sharedFormat.minorVersion()); - format.setProfile(sharedFormat.profile()); + int major; + int minor; + QSurfaceFormat::OpenGLContextProfile profile; + +#ifdef Q_OS_MACOS + // Due to QTBUG-63180, requesting the sharedFormat.majorVersion() on macOS will lead to + // a failed creation of QQuickWidget shared context. Thus make sure to request the + // major version specified in the defaultFormat instead. + major = defaultFormat.majorVersion(); + minor = defaultFormat.minorVersion(); + profile = defaultFormat.profile(); +#else + major = sharedFormat.majorVersion(); + minor = sharedFormat.minorVersion(); + profile = sharedFormat.profile(); +#endif + format.setMajorVersion(major); + format.setMinorVersion(minor); + format.setProfile(profile); } } @@ -162,7 +178,14 @@ RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(Rende void RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete() { + // Unset the parent, because parent is being destroyed, but the owner of this + // RenderWidgetHostViewQtDelegateWidget is actually a RenderWidgetHostViewQt instance. setParent(Q_NULLPTR); + + // If this widget represents a popup window, make sure to close it, so that if the popup was the + // last visible top level window, the application event loop can quit if it deems it necessarry. + if (m_isPopup) + close(); } void RenderWidgetHostViewQtDelegateWidget::initAsChild(WebContentsAdapterClient* container) @@ -430,6 +453,9 @@ bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event) case QEvent::DragLeave: case QEvent::DragMove: case QEvent::Drop: + case QEvent::HoverEnter: + case QEvent::HoverLeave: + case QEvent::HoverMove: // Let the parent handle these events. return false; default: |