diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2016-11-24 12:32:08 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2016-11-24 12:32:39 +0100 |
commit | f2f20462e146508868d488f9bc370c53e000d2d9 (patch) | |
tree | 52022ca4c648807543ae2b8f48421b2e5a6df7d6 /src | |
parent | b4f8480fd41a806abe04e8eb2a4c416b2eff53c6 (diff) | |
parent | ecfb3ba8a7eb116c838a1acd5b82ca59ce76b082 (diff) |
Merge remote-tracking branch 'origin/5.8' into dev
Change-Id: Ib2a1eb4dfae2fb5a98066d3d0f8f09f4e1d61d3f
Diffstat (limited to 'src')
66 files changed, 531 insertions, 233 deletions
diff --git a/src/3rdparty b/src/3rdparty -Subproject 7824a683f0d5c93e6b8fd5dfc75d51d06167f0c +Subproject f5a732820b31651bafc60cd64f85b85c7f82532 diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro index cb9d33087..37f8885bb 100644 --- a/src/core/api/core_api.pro +++ b/src/core/api/core_api.pro @@ -15,9 +15,7 @@ CONFIG -= create_prl # Copy this logic from qt_module.prf so that the intermediate library can be # created to the same rules as the final module linking in core_module.pro. !host_build:if(win32|mac):!macx-xcode { - qtConfig(simulator_and_device): CONFIG += simulator_and_device - qtConfig(debug_and_release): CONFIG += debug_and_release - qtConfig(build_all): CONFIG += build_all + qtConfig(debug_and_release): CONFIG += debug_and_release build_all } DEFINES += \ diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp index 86808e177..3396f73ef 100644 --- a/src/core/browser_context_adapter.cpp +++ b/src/core/browser_context_adapter.cpp @@ -491,19 +491,19 @@ void BrowserContextAdapter::clearHttpCache() m_browserContext->url_request_getter_->clearHttpCache(); } -void BrowserContextAdapter::setSpellCheckLanguage(const QString &language) +void BrowserContextAdapter::setSpellCheckLanguages(const QStringList &languages) { #if defined(ENABLE_SPELLCHECK) - m_browserContext->setSpellCheckLanguage(language); + m_browserContext->setSpellCheckLanguages(languages); #endif } -QString BrowserContextAdapter::spellCheckLanguage() const +QStringList BrowserContextAdapter::spellCheckLanguages() const { #if defined(ENABLE_SPELLCHECK) - return m_browserContext->spellCheckLanguage(); + return m_browserContext->spellCheckLanguages(); #else - return QString(); + return QStringList(); #endif } diff --git a/src/core/browser_context_adapter.h b/src/core/browser_context_adapter.h index a6e5a2a3e..39b9db61c 100644 --- a/src/core/browser_context_adapter.h +++ b/src/core/browser_context_adapter.h @@ -108,9 +108,8 @@ public: QString httpUserAgent() const; void setHttpUserAgent(const QString &userAgent); - QStringList spellCheckLanguages(const QStringList &acceptLanguages); - void setSpellCheckLanguage(const QString &language); - QString spellCheckLanguage() const; + void setSpellCheckLanguages(const QStringList &language); + QStringList spellCheckLanguages() const; void setSpellCheckEnabled(bool enabled); bool isSpellCheckEnabled() const; diff --git a/src/core/browser_context_qt.cpp b/src/core/browser_context_qt.cpp index 5f544ab86..a6801e1d7 100644 --- a/src/core/browser_context_qt.cpp +++ b/src/core/browser_context_qt.cpp @@ -213,18 +213,27 @@ void BrowserContextQt::failedToLoadDictionary(const std::string &language) << "Make sure that correct bdic file is in:" << toQt(WebEngineLibraryInfo::getPath(base::DIR_APP_DICTIONARIES).value()); } -void BrowserContextQt::setSpellCheckLanguage(const QString &language) +void BrowserContextQt::setSpellCheckLanguages(const QStringList &languages) { - base::ListValue dictionaries; - dictionaries.AppendString(language.toStdString()); - m_prefService->Set(prefs::kSpellCheckDictionaries, dictionaries); + StringListPrefMember dictionaries_pref; + dictionaries_pref.Init(prefs::kSpellCheckDictionaries, m_prefService.get()); + std::vector<std::string> dictionaries; + dictionaries.reserve(languages.size()); + for (const auto &language : languages) + dictionaries.push_back(language.toStdString()); + dictionaries_pref.SetValue(dictionaries); } -QString BrowserContextQt::spellCheckLanguage() const +QStringList BrowserContextQt::spellCheckLanguages() const { - std::string dictionary; - m_prefService->GetList(prefs::kSpellCheckDictionaries)->GetString(0, &dictionary); - return QString::fromStdString(dictionary); + QStringList spellcheck_dictionaries; + for (const auto &value : *m_prefService->GetList(prefs::kSpellCheckDictionaries)) { + std::string dictionary; + if (value->GetAsString(&dictionary)) + spellcheck_dictionaries.append(QString::fromStdString(dictionary)); + } + + return spellcheck_dictionaries; } void BrowserContextQt::setSpellCheckEnabled(bool enabled) diff --git a/src/core/browser_context_qt.h b/src/core/browser_context_qt.h index 41a85b1b0..ca65552be 100644 --- a/src/core/browser_context_qt.h +++ b/src/core/browser_context_qt.h @@ -101,9 +101,9 @@ public: BrowserContextAdapter *adapter() { return m_adapter; } #if defined(ENABLE_SPELLCHECK) - void failedToLoadDictionary(const std::string& language); - void setSpellCheckLanguage(const QString &language); - QString spellCheckLanguage() const; + void failedToLoadDictionary(const std::string& language) override; + void setSpellCheckLanguages(const QStringList &languages); + QStringList spellCheckLanguages() const; void setSpellCheckEnabled(bool enabled); bool isSpellCheckEnabled() const; #endif diff --git a/src/core/chrome_qt.gyp b/src/core/chrome_qt.gyp index 547f240ea..89f1fe188 100644 --- a/src/core/chrome_qt.gyp +++ b/src/core/chrome_qt.gyp @@ -113,7 +113,7 @@ '<(chromium_src_dir)/third_party/WebKit', ], 'dependencies': [ - '<(chromium_src_dir)/chrome/tools/convert_dict/convert_dict.gyp:convert_dict_lib', + '<(chromium_src_dir)/chrome/tools/convert_dict/convert_dict.gyp:convert_dict', '<(chromium_src_dir)/third_party/hunspell/hunspell.gyp:hunspell', '<(chromium_src_dir)/third_party/icu/icu.gyp:icui18n', '<(chromium_src_dir)/third_party/icu/icu.gyp:icuuc', @@ -132,6 +132,8 @@ 'sources!': [ '<(DEPTH)/chrome/renderer/spellchecker/platform_spelling_engine.cc', '<(DEPTH)/chrome/renderer/spellchecker/platform_spelling_engine.h', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_message_filter_platform.h', + '<(DEPTH)/chrome/browser/spellchecker/spellcheck_message_filter_platform_mac.cc', ], }], ], diff --git a/src/core/config/common.pri b/src/core/config/common.pri index 01c942976..7a9656fca 100644 --- a/src/core/config/common.pri +++ b/src/core/config/common.pri @@ -10,3 +10,8 @@ GYP_CONFIG += v8_use_external_startup_data=0 GYP_CONFIG += enable_web_speech=0 # We do not use or even include the extensions GYP_CONFIG += enable_extensions=0 + +sanitize_address: GYP_CONFIG += asan=1 +sanitize_thread: GYP_CONFIG += tsan=1 +sanitize_memory: GYP_CONFIG += msan=1 +sanitize_undefined: GYP_CONFIG += ubsan=1 diff --git a/src/core/config/desktop_linux.pri b/src/core/config/desktop_linux.pri index 46d500207..e28d7eb7c 100644 --- a/src/core/config/desktop_linux.pri +++ b/src/core/config/desktop_linux.pri @@ -8,7 +8,11 @@ GYP_CONFIG += \ enable_pdf=1 clang { - GYP_CONFIG += clang=1 host_clang=1 clang_use_chrome_plugins=0 make_clang_dir=/usr + GYP_CONFIG += werror= + clang_full_path = $$which($${QMAKE_CXX}) + # Remove the "/bin/clang++" part. + clang_prefix = $$section(clang_full_path, /, 0, -3) + GYP_CONFIG += clang=1 host_clang=1 clang_use_chrome_plugins=0 make_clang_dir=$${clang_prefix} linux-clang-libc++: GYP_CONFIG += use_system_libcxx=1 } else { GYP_CONFIG += clang=0 host_clang=0 diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri index fc2b124fb..83c852f86 100644 --- a/src/core/config/linux.pri +++ b/src/core/config/linux.pri @@ -39,7 +39,7 @@ gcc:!clang: greaterThan(QT_GCC_MAJOR_VERSION, 5): GYP_CONFIG += no_delete_null_p qtConfig(system-zlib): use?(system_minizip): GYP_CONFIG += use_system_zlib=1 qtConfig(system-png): GYP_CONFIG += use_system_libpng=1 qtConfig(system-jpeg): GYP_CONFIG += use_system_libjpeg=1 -qtConfig(system-harfbuzz): GYP_CONFIG += use_system_harfbuzz=1 +qtConfig(system-harfbuzz): use?(system_harfbuzz): GYP_CONFIG += use_system_harfbuzz=1 !qtConfig(glib): GYP_CONFIG += use_glib=0 contains(QT_CONFIG, pulseaudio) { GYP_CONFIG += use_pulseaudio=1 diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index 64964dc09..787586540 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -44,11 +44,15 @@ #include "base/threading/thread_restrictions.h" #if defined(ENABLE_SPELLCHECK) #include "chrome/browser/spellchecker/spellcheck_message_filter.h" +#if defined(USE_BROWSER_SPELLCHECKER) +#include "chrome/browser/spellchecker/spellcheck_message_filter_platform.h" +#endif #endif #include "content/browser/renderer_host/render_view_host_delegate.h" #include "content/public/browser/browser_main_parts.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/geolocation_delegate.h" +#include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/media_observer.h" #include "content/public/browser/quota_permission_context.h" #include "content/public/browser/render_frame_host.h" @@ -81,6 +85,7 @@ #if defined(ENABLE_BASIC_PRINTING) #include "printing_message_filter_qt.h" #endif // defined(ENABLE_BASIC_PRINTING) +#include "qrc_protocol_handler_qt.h" #include "renderer_host/resource_dispatcher_host_delegate_qt.h" #include "renderer_host/user_resource_controller_host.h" #include "web_contents_delegate_qt.h" @@ -280,7 +285,8 @@ public: m_handle = pni->nativeResourceForContext(QByteArrayLiteral("cglcontextobj"), qtContext); else if (platform == QLatin1String("qnx")) m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), qtContext); - else if (platform == QLatin1String("eglfs") || platform == QLatin1String("wayland")) + else if (platform == QLatin1String("eglfs") || platform == QLatin1String("wayland") + || platform == QLatin1String("wayland-egl")) m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), qtContext); else if (platform == QLatin1String("windows")) { if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2) @@ -377,8 +383,12 @@ void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost* host->AddFilter(new BrowserMessageFilterQt(id)); #endif #if defined(ENABLE_SPELLCHECK) + // SpellCheckMessageFilter is required for both Hunspell and Native configurations. host->AddFilter(new SpellCheckMessageFilter(id)); #endif +#if defined(Q_OS_MACOS) && defined(USE_BROWSER_SPELLCHECKER) + host->AddFilter(new SpellCheckMessageFilterPlatform(id)); +#endif #if defined(ENABLE_BASIC_PRINTING) host->AddFilter(new PrintingMessageFilterQt(host->GetID())); #endif // defined(ENABLE_BASIC_PRINTING) @@ -472,6 +482,13 @@ void ContentBrowserClientQt::AllowCertificateError(content::WebContents *webCont *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY; } +void ContentBrowserClientQt::SelectClientCertificate(content::WebContents * /*webContents*/, + net::SSLCertRequestInfo * /*certRequestInfo*/, + std::unique_ptr<content::ClientCertificateDelegate> delegate) +{ + delegate->ContinueWithCertificate(nullptr); +} + std::string ContentBrowserClientQt::GetApplicationLocale() { return WebEngineLibraryInfo::getApplicationLocale(); @@ -491,6 +508,11 @@ void ContentBrowserClientQt::AppendExtraCommandLineSwitches(base::CommandLine* c command_line->AppendSwitchASCII(switches::kLang, GetApplicationLocale()); } +void ContentBrowserClientQt::GetAdditionalWebUISchemes(std::vector<std::string>* additional_schemes) +{ + additional_schemes->push_back(kQrcSchemeQt); +} + #if defined(Q_OS_LINUX) void ContentBrowserClientQt::GetAdditionalMappedFilesForChildProcess(const base::CommandLine& command_line, int child_process_id, content::FileDescriptorInfo* mappings) { diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h index acbf1a059..a13d14ff2 100644 --- a/src/core/content_browser_client_qt.h +++ b/src/core/content_browser_client_qt.h @@ -100,11 +100,15 @@ public: bool expired_previous_decision, const base::Callback<void(bool)>& callback, content::CertificateRequestResultType* result) Q_DECL_OVERRIDE; + virtual void SelectClientCertificate(content::WebContents* web_contents, + net::SSLCertRequestInfo* cert_request_info, + std::unique_ptr<content::ClientCertificateDelegate> delegate) Q_DECL_OVERRIDE; content::DevToolsManagerDelegate *GetDevToolsManagerDelegate() Q_DECL_OVERRIDE; virtual std::string GetApplicationLocale() Q_DECL_OVERRIDE; std::string GetAcceptLangs(content::BrowserContext* context) Q_DECL_OVERRIDE; virtual void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) Q_DECL_OVERRIDE; + virtual void GetAdditionalWebUISchemes(std::vector<std::string>* additional_schemes) Q_DECL_OVERRIDE; #if defined(Q_OS_LINUX) virtual void GetAdditionalMappedFilesForChildProcess(const base::CommandLine& command_line, int child_process_id, content::FileDescriptorInfo* mappings) Q_DECL_OVERRIDE; diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp index 0dac5e48b..5d51f65aa 100644 --- a/src/core/content_client_qt.cpp +++ b/src/core/content_client_qt.cpp @@ -166,7 +166,8 @@ void AddPepperFlashFromSystem(std::vector<content::PepperPluginInfo>* plugins) #endif #if defined(Q_OS_LINUX) pluginPaths << "/opt/google/chrome/PepperFlash/libpepflashplayer.so" // Google Chrome - << "/usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so" // Ubuntu + << "/usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so" // Ubuntu, package pepperflashplugin-nonfree + << "/usr/lib/adobe-flashplugin/libpepflashplayer.so" // Ubuntu, package adobe-flashplugin << "/usr/lib/PepperFlash/libpepflashplayer.so" // Arch << "/usr/lib64/chromium/PepperFlash/libpepflashplayer.so"; // OpenSuSE pluginPaths << ppapiPluginsPath() + QStringLiteral("/libpepflashplayer.so"); diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp index 44e37aeb6..baf064025 100644 --- a/src/core/delegated_frame_node.cpp +++ b/src/core/delegated_frame_node.cpp @@ -111,6 +111,10 @@ #define GL_RGB 0x1907 #endif +#ifndef GL_LINE_LOOP +#define GL_LINE_LOOP 0x0002 +#endif + namespace QtWebEngineCore { #ifndef QT_NO_OPENGL class MailboxTexture : public QSGTexture, protected QOpenGLFunctions { @@ -642,7 +646,7 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, QSGGeometryNode *geometryNode = new QSGGeometryNode; QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4); - geometry->setDrawingMode(QSGGeometry::DrawLineLoop); + geometry->setDrawingMode(GL_LINE_LOOP); geometry->setLineWidth(dbquad->width); // QSGGeometry::updateRectGeometry would actually set the corners in the following order: // top-left, bottom-left, top-right, bottom-right, leading to a nice criss cross, instead diff --git a/src/core/doc/src/qtwebenginecore-index.qdoc b/src/core/doc/src/qtwebenginecore-index.qdoc index 70af397ce..4d540e277 100644 --- a/src/core/doc/src/qtwebenginecore-index.qdoc +++ b/src/core/doc/src/qtwebenginecore-index.qdoc @@ -28,7 +28,6 @@ /*! \page qtwebenginecore-index.html \title Qt WebEngine Core - \ingroup modules \brief Provides common API shared by Qt WebEngine and Qt WebEngine Widgets. diff --git a/src/core/doc/src/qtwebenginecore-module.qdoc b/src/core/doc/src/qtwebenginecore-module.qdoc index 6dc2478fc..0ac20a794 100644 --- a/src/core/doc/src/qtwebenginecore-module.qdoc +++ b/src/core/doc/src/qtwebenginecore-module.qdoc @@ -32,6 +32,7 @@ \brief Provides public API shared by both QtWebEngine and QtWebEngineWidgets \since 5.6 \ingroup qtwebengine-modules + \ingroup modules To include the definitions of the module's classes, use the following directive: diff --git a/src/core/gl_context_qt.cpp b/src/core/gl_context_qt.cpp index b1177a998..a1855b060 100644 --- a/src/core/gl_context_qt.cpp +++ b/src/core/gl_context_qt.cpp @@ -122,7 +122,7 @@ void* GLContextHelper::getXConfig() void* GLContextHelper::getEGLDisplay() { - return resourceForContext(QByteArrayLiteral("egldisplay")); + return resourceForIntegration(QByteArrayLiteral("egldisplay")); } void* GLContextHelper::getXDisplay() diff --git a/src/core/gl_surface_qt.cpp b/src/core/gl_surface_qt.cpp index e88a26715..74bb32d1f 100644 --- a/src/core/gl_surface_qt.cpp +++ b/src/core/gl_surface_qt.cpp @@ -90,6 +90,9 @@ void* g_display; const char* g_extensions = NULL; bool g_egl_surfaceless_context_supported = false; + +bool g_initializedEGL = false; + } // namespace @@ -573,11 +576,17 @@ bool InitializeGLOneOffPlatform() return GLSurfaceQtEGL::InitializeOneOff(); if (GetGLImplementation() == kGLImplementationDesktopGL) { -#if defined(USE_X11) - return GLSurfaceQtGLX::InitializeOneOff(); -#elif defined(OS_WIN) +#if defined(OS_WIN) return GLSurfaceQtWGL::InitializeOneOff(); +#elif defined(USE_X11) + if (GLSurfaceQtGLX::InitializeOneOff()) + return true; #endif + // Fallback to trying EGL with desktop GL. + if (GLSurfaceQtEGL::InitializeOneOff()) { + g_initializedEGL = true; + return true; + } } return false; @@ -586,40 +595,40 @@ bool InitializeGLOneOffPlatform() scoped_refptr<GLSurface> CreateOffscreenGLSurface(const gfx::Size& size) { + scoped_refptr<GLSurface> surface; switch (GetGLImplementation()) { case kGLImplementationDesktopGLCoreProfile: case kGLImplementationDesktopGL: { -#if defined(USE_X11) - scoped_refptr<GLSurface> surface = new GLSurfaceQtGLX(size); - if (!surface->Initialize()) - return NULL; - return surface; -#elif defined(OS_WIN) - scoped_refptr<GLSurface> surface = new GLSurfaceQtWGL(size); - if (!surface->Initialize()) - return NULL; - return surface; -#else - LOG(ERROR) << "Desktop GL is not supported on this platform."; - Q_UNREACHABLE(); - return NULL; +#if defined(OS_WIN) + surface = new GLSurfaceQtWGL(size); + if (surface->Initialize()) + return surface; + break; +#elif defined(USE_X11) + if (!g_initializedEGL) { + surface = new GLSurfaceQtGLX(size); + if (surface->Initialize()) + return surface; + } + // no break #endif } case kGLImplementationEGLGLES2: { - scoped_refptr<GLSurface> surface; if (g_egl_surfaceless_context_supported) surface = new GLSurfacelessQtEGL(size); else surface = new GLSurfaceQtEGL(size); - if (!surface->Initialize()) - return NULL; - return surface; + if (surface->Initialize()) + return surface; + break; } default: - Q_UNREACHABLE(); - return NULL; + break; } + LOG(ERROR) << "Requested OpenGL platform is not supported."; + Q_UNREACHABLE(); + return NULL; } scoped_refptr<GLSurface> diff --git a/src/core/gyp_run.pro b/src/core/gyp_run.pro index 89b751c4a..1850447e7 100644 --- a/src/core/gyp_run.pro +++ b/src/core/gyp_run.pro @@ -36,9 +36,7 @@ force_debug_info { # Copy this logic from qt_module.prf so that ninja can run according # to the same rules as the final module linking in core_module.pro. !host_build:if(win32|mac):!macx-xcode { - qtConfig(simulator_and_device): CONFIG += simulator_and_device - qtConfig(debug_and_release): CONFIG += debug_and_release - qtConfig(build_all): CONFIG += build_all + qtConfig(debug_and_release): CONFIG += debug_and_release build_all } cross_compile { @@ -122,12 +120,18 @@ contains(WEBENGINE_CONFIG, use_appstore_compliant_code): GYP_CONFIG += appstore_ # but the latter are necessary for useful debug binaries. contains(WEBENGINE_CONFIG, reduce_binary_size): GYP_CONFIG += release_optimize=s debug_optimize=s release_unwind_tables=0 -contains(WEBENGINE_CONFIG, no_spellcheck): { +!contains(WEBENGINE_CONFIG, use_spellchecker): { GYP_CONFIG += enable_spellcheck=0 - osx: GYP_CONFIG += use_browser_spellchecker=0 + macos: GYP_CONFIG += use_browser_spellchecker=0 } else { GYP_CONFIG += enable_spellcheck=1 - osx: GYP_CONFIG += use_browser_spellchecker=1 + macos { + contains(WEBENGINE_CONFIG, use_native_spellchecker) { + GYP_CONFIG += use_browser_spellchecker=1 + } else { + GYP_CONFIG += use_browser_spellchecker=0 + } + } } !qtConfig(framework):qtConfig(private_tests) { diff --git a/src/core/media_capture_devices_dispatcher.cpp b/src/core/media_capture_devices_dispatcher.cpp index 3e260587c..f06f0150f 100644 --- a/src/core/media_capture_devices_dispatcher.cpp +++ b/src/core/media_capture_devices_dispatcher.cpp @@ -173,7 +173,6 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content: if (securityOriginsMatch && (microphoneRequested || webcamRequested)) { switch (request.request_type) { case content::MEDIA_OPEN_DEVICE_PEPPER_ONLY: - Q_UNREACHABLE(); // only speculative as this is for Pepper getDefaultDevices("", "", microphoneRequested, webcamRequested, &devices); break; case content::MEDIA_DEVICE_ACCESS: diff --git a/src/core/pdfium_printing_wrapper_qt.cpp b/src/core/pdfium_printing_wrapper_qt.cpp index 165ac743f..fceb381af 100644 --- a/src/core/pdfium_printing_wrapper_qt.cpp +++ b/src/core/pdfium_printing_wrapper_qt.cpp @@ -139,7 +139,9 @@ PdfiumPrintingWrapperQt::PdfiumPrintingWrapperQt(const void *pdfData, size_t siz bool PdfiumPrintingWrapperQt::printOnPrinter(QPrinter &printer) { if (!m_documentHandle || !m_pageCount) { +#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) qWarning("Failure to print on printer %ls: invalid document.\n", qUtf16Printable(printer.printerName())); +#endif return false; } @@ -172,7 +174,9 @@ bool PdfiumPrintingWrapperQt::printOnPrinter(QPrinter &printer) QPainter painter; if (!painter.begin(&printer)) { +#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) qWarning("Failure to print on printer %ls: Could not open printer for painting.\n", qUtf16Printable(printer.printerName())); +#endif return false; } diff --git a/src/core/print_view_manager_qt.cpp b/src/core/print_view_manager_qt.cpp index 8f52cc24a..0231df8bd 100644 --- a/src/core/print_view_manager_qt.cpp +++ b/src/core/print_view_manager_qt.cpp @@ -136,14 +136,16 @@ static base::DictionaryValue *createPrintSettings() return printSettings; } -static void applyQPageLayoutSettingsToDictionary(const QPageLayout &pageLayout, base::DictionaryValue &printSettings) +static base::DictionaryValue *createPrintSettingsFromQPageLayout(const QPageLayout &pageLayout) { + base::DictionaryValue *printSettings = createPrintSettings(); + //Set page size attributes, chromium expects these in micrometers QSizeF pageSizeInMilimeter = pageLayout.pageSize().size(QPageSize::Millimeter); std::unique_ptr<base::DictionaryValue> sizeDict(new base::DictionaryValue); sizeDict->SetInteger(printing::kSettingMediaSizeWidthMicrons, pageSizeInMilimeter.width() * kMicronsToMillimeter); sizeDict->SetInteger(printing::kSettingMediaSizeHeightMicrons, pageSizeInMilimeter.height() * kMicronsToMillimeter); - printSettings.Set(printing::kSettingMediaSize, std::move(sizeDict)); + printSettings->Set(printing::kSettingMediaSize, std::move(sizeDict)); // Apply page margins QMargins pageMarginsInPoints = pageLayout.marginsPoints(); @@ -152,10 +154,13 @@ static void applyQPageLayoutSettingsToDictionary(const QPageLayout &pageLayout, marginsDict->SetInteger(printing::kSettingMarginBottom, pageMarginsInPoints.bottom()); marginsDict->SetInteger(printing::kSettingMarginLeft, pageMarginsInPoints.left()); marginsDict->SetInteger(printing::kSettingMarginRight, pageMarginsInPoints.right()); - printSettings.Set(printing::kSettingMarginsCustom, std::move(marginsDict)); - printSettings.SetInteger(printing::kSettingMarginsType, printing::CUSTOM_MARGINS); - printSettings.SetBoolean(printing::kSettingLandscape, pageLayout.orientation() == QPageLayout::Landscape); + printSettings->Set(printing::kSettingMarginsCustom, std::move(marginsDict)); + printSettings->SetInteger(printing::kSettingMarginsType, printing::CUSTOM_MARGINS); + + printSettings->SetBoolean(printing::kSettingLandscape, pageLayout.orientation() == QPageLayout::Landscape); + + return printSettings; } } // namespace @@ -209,12 +214,11 @@ bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout, bool { if (!pageLayout.isValid()) return false; - m_printSettings.reset(createPrintSettings()); - m_printSettings->SetInteger(printing::kSettingColor, printInColor ? printing::COLOR : printing::GRAYSCALE); - applyQPageLayoutSettingsToDictionary(pageLayout, *m_printSettings); + m_printSettings.reset(createPrintSettingsFromQPageLayout(pageLayout)); m_printSettings->SetBoolean(printing::kSettingShouldPrintBackgrounds , web_contents()->GetRenderViewHost()->GetWebkitPreferences().should_print_backgrounds); + m_printSettings->SetInteger(printing::kSettingColor, printInColor ? printing::COLOR : printing::GRAYSCALE); return Send(new PrintMsg_InitiatePrintPreview(routing_id(), false)); } diff --git a/src/core/proxy_config_service_qt.cpp b/src/core/proxy_config_service_qt.cpp index 28a36d37f..a6ffb39ab 100644 --- a/src/core/proxy_config_service_qt.cpp +++ b/src/core/proxy_config_service_qt.cpp @@ -109,10 +109,13 @@ net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxy } m_qtApplicationProxy = qtProxy; m_qtProxyConfig = net::ProxyConfig(); - if (qtProxy.type() == QNetworkProxy::NoProxy) { +#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) + if (qtProxy.type() == QNetworkProxy::NoProxy + && QNetworkProxyFactory::usesSystemConfiguration()) { *config = systemConfig; return systemAvailability; } +#endif net::ProxyConfig::ProxyRules qtRules; net::ProxyServer server = fromQNetworkProxy(qtProxy); diff --git a/src/core/qrc_protocol_handler_qt.cpp b/src/core/qrc_protocol_handler_qt.cpp index 222961762..eb716f182 100644 --- a/src/core/qrc_protocol_handler_qt.cpp +++ b/src/core/qrc_protocol_handler_qt.cpp @@ -46,6 +46,8 @@ namespace QtWebEngineCore { +const char kQrcSchemeQt[] = "qrc"; + QrcProtocolHandlerQt::QrcProtocolHandlerQt() { } diff --git a/src/core/qrc_protocol_handler_qt.h b/src/core/qrc_protocol_handler_qt.h index 53d063810..a2e0cc00b 100644 --- a/src/core/qrc_protocol_handler_qt.h +++ b/src/core/qrc_protocol_handler_qt.h @@ -53,6 +53,8 @@ class URLRequestJob; namespace QtWebEngineCore { +extern const char kQrcSchemeQt[]; + // Implements a ProtocolHandler for qrc file jobs. If |network_delegate_| is NULL, // then all file requests will fail with ERR_ACCESS_DENIED. class QrcProtocolHandlerQt : public net::URLRequestJobFactory::ProtocolHandler { diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp index a6e35f4be..69f5bfefe 100644 --- a/src/core/renderer/content_renderer_client_qt.cpp +++ b/src/core/renderer/content_renderer_client_qt.cpp @@ -135,6 +135,12 @@ void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame* render_fr void ContentRendererClientQt::RunScriptsAtDocumentStart(content::RenderFrame* render_frame) { + // Check whether the render_frame has been created and has not been detached yet. + // Otherwise the WebFrame is not available. + RenderFrameObserverQt *render_frame_observer = RenderFrameObserverQt::Get(render_frame); + if (!render_frame_observer || render_frame_observer->isFrameDetached()) + return; // The frame is invisible to scripts. + if (WebChannelIPCTransport *transport = WebChannelIPCTransport::Get(render_frame->GetRenderView())) transport->RunScriptsAtDocumentStart(render_frame); UserResourceController::instance()->RunScriptsAtDocumentStart(render_frame); @@ -142,6 +148,12 @@ void ContentRendererClientQt::RunScriptsAtDocumentStart(content::RenderFrame* re void ContentRendererClientQt::RunScriptsAtDocumentEnd(content::RenderFrame* render_frame) { + // Check whether the render_frame has been created and has not been detached yet. + // Otherwise the WebFrame is not available. + RenderFrameObserverQt *render_frame_observer = RenderFrameObserverQt::Get(render_frame); + if (!render_frame_observer || render_frame_observer->isFrameDetached()) + return; // The frame is invisible to scripts. + UserResourceController::instance()->RunScriptsAtDocumentEnd(render_frame); } diff --git a/src/core/renderer/render_frame_observer_qt.cpp b/src/core/renderer/render_frame_observer_qt.cpp index 77bc89f67..53e9407db 100644 --- a/src/core/renderer/render_frame_observer_qt.cpp +++ b/src/core/renderer/render_frame_observer_qt.cpp @@ -55,6 +55,8 @@ namespace QtWebEngineCore { RenderFrameObserverQt::RenderFrameObserverQt(content::RenderFrame* render_frame) : RenderFrameObserver(render_frame) + , RenderFrameObserverTracker<RenderFrameObserverQt>(render_frame) + , m_isFrameDetached(false) { } @@ -72,4 +74,14 @@ void RenderFrameObserverQt::DidCreatePepperPlugin(content::RendererPpapiHost* ho } #endif +void RenderFrameObserverQt::FrameDetached() +{ + m_isFrameDetached = true; +} + +bool RenderFrameObserverQt::isFrameDetached() const +{ + return m_isFrameDetached; +} + } // namespace QtWebEngineCore diff --git a/src/core/renderer/render_frame_observer_qt.h b/src/core/renderer/render_frame_observer_qt.h index c59b7babc..b74be5cd1 100644 --- a/src/core/renderer/render_frame_observer_qt.h +++ b/src/core/renderer/render_frame_observer_qt.h @@ -42,6 +42,7 @@ #include "base/compiler_specific.h" #include "content/public/renderer/render_frame_observer.h" +#include "content/public/renderer/render_frame_observer_tracker.h" namespace content { @@ -50,7 +51,10 @@ class RenderFrame; namespace QtWebEngineCore { -class RenderFrameObserverQt : public content::RenderFrameObserver { +class RenderFrameObserverQt + : public content::RenderFrameObserver + , public content::RenderFrameObserverTracker<RenderFrameObserverQt> +{ public: explicit RenderFrameObserverQt(content::RenderFrame* render_frame); ~RenderFrameObserverQt(); @@ -59,9 +63,14 @@ public: void DidCreatePepperPlugin(content::RendererPpapiHost* host) override; #endif void OnDestruct() override { } + void FrameDetached() override; + + bool isFrameDetached() const; private: DISALLOW_COPY_AND_ASSIGN(RenderFrameObserverQt); + + bool m_isFrameDetached; }; } // namespace QtWebEngineCore diff --git a/src/core/renderer/web_channel_ipc_transport.cpp b/src/core/renderer/web_channel_ipc_transport.cpp index 3a44bb182..161d6f493 100644 --- a/src/core/renderer/web_channel_ipc_transport.cpp +++ b/src/core/renderer/web_channel_ipc_transport.cpp @@ -164,9 +164,8 @@ void WebChannelIPCTransport::RunScriptsAtDocumentStart(content::RenderFrame *ren { // JavaScript run before this point doesn't stick, and needs to be redone. // ### FIXME: we should try no even installing before - blink::WebLocalFrame *frame = render_frame->GetWebFrame(); if (m_installed && render_frame->IsMainFrame()) - WebChannelTransport::Install(frame, m_installedWorldId); + WebChannelTransport::Install(render_frame->GetWebFrame(), m_installedWorldId); } @@ -224,9 +223,12 @@ void WebChannelIPCTransport::dispatchWebChannelMessage(const std::vector<char> & } v8::Handle<v8::Object> messageObject(v8::Object::New(isolate)); - messageObject->ForceSet(v8::String::NewFromUtf8(isolate, "data") - , v8::String::NewFromUtf8(isolate, json.constData(), v8::String::kNormalString, json.size()) - , v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete)); + v8::Maybe<bool> wasSet = messageObject->DefineOwnProperty( + context, + v8::String::NewFromUtf8(isolate, "data"), + v8::String::NewFromUtf8(isolate, json.constData(), v8::String::kNormalString, json.size()), + v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete)); + Q_ASSERT(!wasSet.IsNothing() && wasSet.FromJust()); v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast(onmessageCallbackValue); const int argc = 1; diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp index 61f359a87..bf4661102 100644 --- a/src/core/url_request_context_getter_qt.cpp +++ b/src/core/url_request_context_getter_qt.cpp @@ -91,8 +91,6 @@ namespace QtWebEngineCore { -static const char kQrcSchemeQt[] = "qrc"; - using content::BrowserThread; URLRequestContextGetterQt::URLRequestContextGetterQt(QSharedPointer<BrowserContextAdapter> browserContext, content::ProtocolHandlerMap *protocolHandlers, content::URLRequestInterceptorScopedVector request_interceptors) diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index c8d93b3f0..fadbd6d2e 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -351,7 +351,6 @@ WebContentsAdapterPrivate::WebContentsAdapterPrivate() , adapterClient(0) , nextRequestId(CallbackDirectory::ReservedCallbackIdsEnd) , lastFindRequestId(0) - , currentDropData(nullptr) , currentDropAction(Qt::IgnoreAction) , inDragUpdateLoop(false) , updateDragCursorMessagePollingTimer(new QTimer) @@ -1114,18 +1113,12 @@ void WebContentsAdapter::setWebChannel(QWebChannel *channel, uint worldId) static QMimeData *mimeDataFromDropData(const content::DropData &dropData) { QMimeData *mimeData = new QMimeData(); - if (!dropData.text.is_null()) { + if (!dropData.text.is_null()) mimeData->setText(toQt(dropData.text.string())); - return mimeData; - } - if (!dropData.html.is_null()) { + if (!dropData.html.is_null()) mimeData->setHtml(toQt(dropData.html.string())); - return mimeData; - } - if (dropData.url.is_valid()) { + if (dropData.url.is_valid()) mimeData->setUrls(QList<QUrl>() << toQt(dropData.url)); - return mimeData; - } return mimeData; } @@ -1140,15 +1133,14 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD // Clear certain fields of the drop data to not run into DCHECKs // of DropDataToWebDragData in render_view_impl.cc. - content::DropData fixedDropData = dropData; - fixedDropData.download_metadata.clear(); - fixedDropData.file_contents.clear(); - fixedDropData.file_description_filename.clear(); + d->currentDropData.reset(new content::DropData(dropData)); + d->currentDropData->download_metadata.clear(); + d->currentDropData->file_contents.clear(); + d->currentDropData->file_description_filename.clear(); d->currentDropAction = Qt::IgnoreAction; - d->currentDropData = &fixedDropData; QDrag *drag = new QDrag(dragSource); // will be deleted by Qt's DnD implementation - drag->setMimeData(mimeDataFromDropData(fixedDropData)); + drag->setMimeData(mimeDataFromDropData(*d->currentDropData)); if (!pixmap.isNull()) { drag->setPixmap(pixmap); drag->setHotSpot(offset); @@ -1161,7 +1153,7 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD content::RenderViewHost *rvh = d->webContents->GetRenderViewHost(); rvh->DragSourceSystemDragEnded(); - d->currentDropData = nullptr; + d->currentDropData.reset(); } static blink::WebDragOperationsMask toWeb(const Qt::DropActions action) @@ -1198,17 +1190,15 @@ void WebContentsAdapter::enterDrag(QDragEnterEvent *e, const QPoint &screenPos) { Q_D(WebContentsAdapter); - std::unique_ptr<content::DropData> ownedDropData; - const content::DropData *rvhDropData = d->currentDropData; - if (!rvhDropData) { + if (!d->currentDropData) { // The drag originated outside the WebEngineView. - ownedDropData.reset(new content::DropData); - fillDropDataFromMimeData(ownedDropData.get(), e->mimeData()); - rvhDropData = ownedDropData.get(); + d->currentDropData.reset(new content::DropData); + fillDropDataFromMimeData(d->currentDropData.get(), e->mimeData()); } content::RenderViewHost *rvh = d->webContents->GetRenderViewHost(); - rvh->DragTargetDragEnter(*rvhDropData, toGfx(e->pos()), toGfx(screenPos), + rvh->FilterDropData(d->currentDropData.get()); + rvh->DragTargetDragEnter(*d->currentDropData, toGfx(e->pos()), toGfx(screenPos), toWeb(e->possibleActions()), flagsFromModifiers(e->keyboardModifiers())); } @@ -1220,6 +1210,16 @@ Qt::DropAction WebContentsAdapter::updateDragPosition(QDragMoveEvent *e, const Q rvh->DragTargetDragOver(toGfx(e->pos()), toGfx(screenPos), toWeb(e->possibleActions()), blink::WebInputEvent::LeftButtonDown); + base::MessageLoop *currentMessageLoop = base::MessageLoop::current(); + DCHECK(currentMessageLoop); + if (!currentMessageLoop->NestableTasksAllowed()) { + // We're already inside a MessageLoop::RunTask call, and scheduled tasks will not be + // executed. That means, updateDragAction will never be called, and the RunLoop below will + // remain blocked forever. + qWarning("WebContentsAdapter::updateDragPosition called from MessageLoop::RunTask."); + return Qt::IgnoreAction; + } + // Wait until we get notified via RenderViewHostDelegateView::UpdateDragCursor. This calls // WebContentsAdapter::updateDragAction that will eventually quit the nested loop. base::RunLoop loop; @@ -1254,7 +1254,9 @@ void WebContentsAdapter::endDragging(const QPoint &clientPos, const QPoint &scre Q_D(WebContentsAdapter); finishDragUpdate(); content::RenderViewHost *rvh = d->webContents->GetRenderViewHost(); + rvh->FilterDropData(d->currentDropData.get()); rvh->DragTargetDrop(*d->currentDropData, toGfx(clientPos), toGfx(screenPos), 0); + d->currentDropData.reset(); } void WebContentsAdapter::leaveDrag() @@ -1263,6 +1265,7 @@ void WebContentsAdapter::leaveDrag() finishDragUpdate(); content::RenderViewHost *rvh = d->webContents->GetRenderViewHost(); rvh->DragTargetDragLeave(); + d->currentDropData.reset(); } void WebContentsAdapter::initUpdateDragCursorMessagePollingTimer() diff --git a/src/core/web_contents_adapter_p.h b/src/core/web_contents_adapter_p.h index 77522d299..23a1aaef4 100644 --- a/src/core/web_contents_adapter_p.h +++ b/src/core/web_contents_adapter_p.h @@ -92,7 +92,7 @@ public: WebContentsAdapterClient *adapterClient; quint64 nextRequestId; int lastFindRequestId; - const content::DropData *currentDropData; + std::unique_ptr<content::DropData> currentDropData; Qt::DropAction currentDropAction; bool inDragUpdateLoop; base::Closure dragUpdateLoopQuitClosure; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index 9d0965818..36acfe62e 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -74,6 +74,7 @@ #include "ui/events/latency_info.h" #include <QDesktopServices> +#include <QTimer> namespace QtWebEngineCore { @@ -107,13 +108,19 @@ content::WebContents *WebContentsDelegateQt::OpenURLFromTab(content::WebContents Q_ASSERT(target); content::NavigationController::LoadURLParams load_url_params(params.url); + load_url_params.source_site_instance = params.source_site_instance; load_url_params.referrer = params.referrer; load_url_params.frame_tree_node_id = params.frame_tree_node_id; + load_url_params.redirect_chain = params.redirect_chain; load_url_params.transition_type = params.transition; load_url_params.extra_headers = params.extra_headers; load_url_params.should_replace_current_entry = params.should_replace_current_entry; load_url_params.is_renderer_initiated = params.is_renderer_initiated; load_url_params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE; + if (params.uses_post) { + load_url_params.load_type = content::NavigationController::LOAD_TYPE_HTTP_POST; + load_url_params.post_data = params.post_data; + } target->GetController().LoadURLWithParams(load_url_params); return target; @@ -320,7 +327,11 @@ void WebContentsDelegateQt::RunFileChooser(content::RenderFrameHost *frameHost, m_filePickerController.reset(new FilePickerController(static_cast<FilePickerController::FileChooserMode>(params.mode), web_contents(), toQt(params.default_file_name.value()), acceptedMimeTypes)); - m_viewClient->runFileChooser(m_filePickerController); + + // Defer the call to not block base::MessageLoop::RunTask with modal dialogs. + QTimer::singleShot(0, [this] () { + m_viewClient->runFileChooser(m_filePickerController); + }); } bool WebContentsDelegateQt::AddMessageToConsole(content::WebContents *source, int32_t level, const base::string16 &message, int32_t line_no, const base::string16 &source_id) diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 7fe8fb612..491835e45 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -309,8 +309,10 @@ WebEngineContext::WebEngineContext() if (useEmbeddedSwitches) { // Inspired by the Android port's default switches - parsedCommandLine->AppendSwitch(switches::kEnableOverlayScrollbar); - parsedCommandLine->AppendSwitch(switches::kEnablePinch); + if (!parsedCommandLine->HasSwitch(switches::kDisableOverlayScrollbar)) + parsedCommandLine->AppendSwitch(switches::kEnableOverlayScrollbar); + if (!parsedCommandLine->HasSwitch(switches::kDisablePinch)) + parsedCommandLine->AppendSwitch(switches::kEnablePinch); parsedCommandLine->AppendSwitch(switches::kEnableViewport); parsedCommandLine->AppendSwitch(switches::kMainFrameResizesAreOrientationChanges); parsedCommandLine->AppendSwitch(switches::kDisableAcceleratedVideoDecode); @@ -325,7 +327,7 @@ WebEngineContext::WebEngineContext() const char *glType = 0; #ifndef QT_NO_OPENGL if (!usingANGLE() && !usingSoftwareDynamicGL() && !usingQtQuick2DRenderer()) { - if (qt_gl_global_share_context()) { + if (qt_gl_global_share_context() && qt_gl_global_share_context()->isValid()) { if (!strcmp(qt_gl_global_share_context()->nativeHandle().typeName(), "QEGLNativeContext")) { if (qt_gl_global_share_context()->isOpenGLES()) { glType = gl::kGLImplementationEGLName; @@ -359,16 +361,7 @@ WebEngineContext::WebEngineContext() glType = gl::kGLImplementationDesktopName; } } else { - qWarning("WebEngineContext used before QtWebEngine::initialize()"); - // We have to assume the default OpenGL module type will be used. - switch (QOpenGLContext::openGLModuleType()) { - case QOpenGLContext::LibGL: - glType = gl::kGLImplementationDesktopName; - break; - case QOpenGLContext::LibGLES: - glType = gl::kGLImplementationEGLName; - break; - } + qWarning("WebEngineContext used before QtWebEngine::initialize() or OpenGL context creation failed."); } } #endif diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp index 2be59d1c6..40977812d 100644 --- a/src/core/web_engine_library_info.cpp +++ b/src/core/web_engine_library_info.cpp @@ -69,7 +69,7 @@ QString fallbackDir() { return directory; } -#if defined(OS_MACOSX) +#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD) static inline CFBundleRef frameworkBundle() { return CFBundleGetBundleWithIdentifier(CFSTR("org.qt-project.Qt.QtWebEngineCore")); @@ -112,6 +112,34 @@ static QString getResourcesPath(CFBundleRef frameworkBundle) } #endif +#if defined(OS_MACOSX) +static QString getMainApplicationResourcesPath() +{ + QString resourcesPath; + CFBundleRef mainBundle = CFBundleGetMainBundle(); + if (!mainBundle) + return resourcesPath; + + // Will point to Resources inside an app bundle, or in case if the application is not packaged + // as a bundle, will point to the application directory, where the resources are assumed to be + // found. + CFURLRef resourcesRelativeUrl = CFBundleCopyResourcesDirectoryURL(mainBundle); + if (!resourcesRelativeUrl) + return resourcesPath; + + CFURLRef resourcesAbsoluteUrl = CFURLCopyAbsoluteURL(resourcesRelativeUrl); + CFStringRef resourcesAbolutePath = CFURLCopyFileSystemPath(resourcesAbsoluteUrl, + kCFURLPOSIXPathStyle); + resourcesPath = QString::fromCFString(resourcesAbolutePath); + CFRelease(resourcesAbolutePath); + CFRelease(resourcesAbsoluteUrl); + CFRelease(resourcesRelativeUrl); + + return resourcesPath; +} + +#endif + QString subProcessPath() { static QString processPath; @@ -181,18 +209,42 @@ QString localesPath() #if defined(ENABLE_SPELLCHECK) QString dictionariesPath() { + static QString potentialDictionariesPath; + static bool initialized = false; + QStringList candidatePaths; + if (!initialized) { + initialized = true; + + // First try to find dictionaries near the application. +#ifdef OS_MACOSX + QString resourcesDictionariesPath = getMainApplicationResourcesPath() + % QDir::separator() % QLatin1String("qtwebengine_dictionaries"); + candidatePaths << resourcesDictionariesPath; +#endif + QString applicationDictionariesPath = QCoreApplication::applicationDirPath() + % QDir::separator() % QLatin1String("qtwebengine_dictionaries"); + candidatePaths << applicationDictionariesPath; + + // Then try to find dictionaries near the installed library. #if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD) - return getResourcesPath(frameworkBundle()) % QLatin1String("/qtwebengine_dictionaries"); -#else - // first local path - static QString potentialDictionariesPath = QCoreApplication::applicationDirPath() % QDir::separator() % QLatin1String("qtwebengine_dictionaries"); + QString frameworkDictionariesPath = getResourcesPath(frameworkBundle()) + % QLatin1String("/qtwebengine_dictionaries"); + candidatePaths << frameworkDictionariesPath; +#endif + + QString libraryDictionariesPath = QLibraryInfo::location(QLibraryInfo::DataPath) + % QDir::separator() % QLatin1String("qtwebengine_dictionaries"); + candidatePaths << libraryDictionariesPath; - // now global one - if (!QFileInfo::exists(potentialDictionariesPath)) - potentialDictionariesPath = QLibraryInfo::location(QLibraryInfo::DataPath) % QDir::separator() % QLatin1String("qtwebengine_dictionaries"); + Q_FOREACH (const QString &candidate, candidatePaths) { + if (QFileInfo::exists(candidate)) { + potentialDictionariesPath = candidate; + break; + } + } + } return potentialDictionariesPath; -#endif } #endif // ENABLE_SPELLCHECK diff --git a/src/src.pro b/src/src.pro index dc6bc5274..9b5373181 100644 --- a/src/src.pro +++ b/src/src.pro @@ -14,8 +14,7 @@ SUBDIRS += core \ plugins # allow only desktop builds of qwebengine_convert_dict -# osx does not use hunspell -!contains(WEBENGINE_CONFIG, no_spellcheck):!osx:!cross_compile { +contains(WEBENGINE_CONFIG, use_spellchecker):!contains(WEBENGINE_CONFIG, use_native_spellchecker):!cross_compile { SUBDIRS += qwebengine_convert_dict qwebengine_convert_dict.subdir = tools/qwebengine_convert_dict qwebengine_convert_dict.depends = core diff --git a/src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro b/src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro index 1781b843d..715081b5f 100644 --- a/src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro +++ b/src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro @@ -1,10 +1,11 @@ option(host_build) # Look for linking information produced by gyp for our target according to core_generated.gyp -!include($$OUT_PWD/../../core/$$getConfigDir()/QtWebEngineCore_linking.pri) { +!include($$OUT_PWD/../../core/$$getConfigDir()/convert_dict_linking.pri) { error("Could not find the linking information that gyp should have generated.") } -# remove object files from linking information + +# skip dummy main.cpp file OBJECTS = # Fixme: -Werror=unused-parameter in core diff --git a/src/webengine/api/qquickwebenginedialogrequests.cpp b/src/webengine/api/qquickwebenginedialogrequests.cpp index 7cb4953fc..641793e12 100644 --- a/src/webengine/api/qquickwebenginedialogrequests.cpp +++ b/src/webengine/api/qquickwebenginedialogrequests.cpp @@ -735,15 +735,15 @@ void QQuickWebEngineFileDialogRequest::dialogReject() onFormValidationMessageRequested: function(request) { request.accepted = true; switch (request.type) { - case FormValidationMessageRequest.RequestTypeShow: + case FormValidationMessageRequest.Show: validationMessage.text = request.text; validationMessage.x = request.x; validationMessage.y = request.y validationMessage.visible = true; break; - case FormValidationMessageRequest.RequestTypeMove: + case FormValidationMessageRequest.Move: break; - case FormValidationMessageRequest.RequestTypeHide: + case FormValidationMessageRequest.Hide: validationMessage.visible = false; break; } @@ -816,11 +816,11 @@ QString QQuickWebEngineFormValidationMessageRequest::subText() const The type of the form validation message request. - \value ValidationMessageRequest.RequestTypeShow + \value ValidationMessageRequest.Show The form validation message should be shown. - \value ValidationMessageRequest.RequestTypeHide + \value ValidationMessageRequest.Hide The form validation message should be hidden. - \value ValidationMessageRequest.RequestTypeMove + \value ValidationMessageRequest.Move The form validation message should be moved. */ diff --git a/src/webengine/api/qquickwebenginedialogrequests_p.h b/src/webengine/api/qquickwebenginedialogrequests_p.h index d1ddc6607..d8a0e004c 100644 --- a/src/webengine/api/qquickwebenginedialogrequests_p.h +++ b/src/webengine/api/qquickwebenginedialogrequests_p.h @@ -228,9 +228,9 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineFormValidationMessageRequest : p Q_OBJECT public: enum RequestType { - RequestTypeShow, - RequestTypeHide, - RequestTypeMove, + Show, + Hide, + Move, }; Q_ENUM(RequestType) Q_PROPERTY(QRect anchor READ anchor CONSTANT FINAL) diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp index 1ca97adea..871428f33 100644 --- a/src/webengine/api/qquickwebengineprofile.cpp +++ b/src/webengine/api/qquickwebengineprofile.cpp @@ -87,8 +87,8 @@ ASSERT_ENUMS_MATCH(QQuickWebEngineDownloadItem::MimeHtmlSaveFormat, QtWebEngineC register custom URL schemes (QQuickWebEngineProfile::installUrlSchemeHandler). Spellchecking HTML form fields can be enabled per profile by setting the \l spellCheckEnabled - property and the current language used for spellchecking can be set by using the - \l spellCheckLanguage property. + property and the current languages used for spellchecking can be set by using the + \l spellCheckLanguages property. */ /*! @@ -618,27 +618,47 @@ QQuickWebEngineProfile *QQuickWebEngineProfile::defaultProfile() } /*! - \property QQuickWebEngineProfile::spellCheckLanguage - \brief the language used by the spell checker. + \property QQuickWebEngineProfile::spellCheckLanguages + \brief The languages used by the spell checker. \since QtWebEngine 1.4 */ /*! - \qmlproperty QString WebEngineProfile::spellCheckLanguage + \qmlproperty list<string> WebEngineProfile::spellCheckLanguages - This property holds the language used by the spell checker. - The language should match the name of the \c .bdic dictionary. - For example, the \a language \c en-US will load the \c en-US.bdic + This property holds the list of languages used by the spell checker. + Each language should match the name of the \c .bdic dictionary. + For example, the language \c en-US will load the \c en-US.bdic dictionary file. - The web engine checks for the \c qtwebengine_dictionaries subdirectory - first in the local directory and if it is not found in the Qt - installation directory: + Qt WebEngine checks for the \c qtwebengine_dictionaries subdirectory + first in the local directory and if it is not found, in the Qt + installation directory. + + On macOS, depending on how Qt WebEngine is configured at build time, there are two possibilities + how spellchecking data is found: + + \list + \li Hunspell dictionaries (default) - .bdic dictionaries are used, just like on other + platforms + \li Native dictionaries - the macOS spellchecking APIs are used (which means the results + will depend on the installed OS dictionaries) + \endlist + + Thus, in the macOS Hunspell case, Qt WebEngine will look in the \e qtwebengine_dictionaries + subdirectory located inside the application bundle \c Resources directory, and also in the + \c Resources directory located inside the Qt framework bundle. + + To summarize, in case of Hunspell usage, the following paths are considered: \list \li QCoreApplication::applicationDirPath()/qtwebengine_dictionaries + or QCoreApplication::applicationDirPath()/../Contents/Resources/qtwebengine_dictionaries + (on macOS) \li [QLibraryInfo::DataPath]/qtwebengine_dictionaries + or path/to/QtWebEngineCore.framework/Resources/qtwebengine_dictionaries (Qt framework + bundle on macOS) \endlist For more information about how to compile \c .bdic dictionaries, see the @@ -646,24 +666,24 @@ QQuickWebEngineProfile *QQuickWebEngineProfile::defaultProfile() \since QtWebEngine 1.4 */ -void QQuickWebEngineProfile::setSpellCheckLanguage(const QString &language) +void QQuickWebEngineProfile::setSpellCheckLanguages(const QStringList &languages) { Q_D(QQuickWebEngineProfile); - if (language != d->browserContext()->spellCheckLanguage()) { - d->browserContext()->setSpellCheckLanguage(language); - emit spellCheckLanguageChanged(); + if (languages != d->browserContext()->spellCheckLanguages()) { + d->browserContext()->setSpellCheckLanguages(languages); + emit spellCheckLanguagesChanged(); } } /*! \since 5.8 - Returns the language used by the spell checker. + Returns the list of languages used by the spell checker. */ -QString QQuickWebEngineProfile::spellCheckLanguage() const +QStringList QQuickWebEngineProfile::spellCheckLanguages() const { const Q_D(QQuickWebEngineProfile); - return d->browserContext()->spellCheckLanguage(); + return d->browserContext()->spellCheckLanguages(); } /*! @@ -674,7 +694,7 @@ QString QQuickWebEngineProfile::spellCheckLanguage() const */ /*! - \qmlproperty QString WebEngineProfile::spellCheckEnabled + \qmlproperty bool WebEngineProfile::spellCheckEnabled This property holds whether the web engine spell checker is enabled. diff --git a/src/webengine/api/qquickwebengineprofile.h b/src/webengine/api/qquickwebengineprofile.h index 577cc7f6a..d0d925930 100644 --- a/src/webengine/api/qquickwebengineprofile.h +++ b/src/webengine/api/qquickwebengineprofile.h @@ -71,7 +71,7 @@ class Q_WEBENGINE_EXPORT QQuickWebEngineProfile : public QObject { Q_PROPERTY(QString httpAcceptLanguage READ httpAcceptLanguage WRITE setHttpAcceptLanguage NOTIFY httpAcceptLanguageChanged FINAL REVISION 1) Q_PROPERTY(PersistentCookiesPolicy persistentCookiesPolicy READ persistentCookiesPolicy WRITE setPersistentCookiesPolicy NOTIFY persistentCookiesPolicyChanged FINAL) Q_PROPERTY(int httpCacheMaximumSize READ httpCacheMaximumSize WRITE setHttpCacheMaximumSize NOTIFY httpCacheMaximumSizeChanged FINAL) - Q_PROPERTY(QString spellCheckLanguage READ spellCheckLanguage WRITE setSpellCheckLanguage NOTIFY spellCheckLanguageChanged FINAL REVISION 3) + Q_PROPERTY(QStringList spellCheckLanguages READ spellCheckLanguages WRITE setSpellCheckLanguages NOTIFY spellCheckLanguagesChanged FINAL REVISION 3) Q_PROPERTY(bool spellCheckEnabled READ isSpellCheckEnabled WRITE setSpellCheckEnabled NOTIFY spellCheckEnabledChanged FINAL REVISION 3) public: @@ -131,8 +131,8 @@ public: Q_REVISION(2) Q_INVOKABLE void clearHttpCache(); - void setSpellCheckLanguage(const QString &language); - QString spellCheckLanguage() const; + void setSpellCheckLanguages(const QStringList &languages); + QStringList spellCheckLanguages() const; void setSpellCheckEnabled(bool enabled); bool isSpellCheckEnabled() const; @@ -148,7 +148,7 @@ Q_SIGNALS: void persistentCookiesPolicyChanged(); void httpCacheMaximumSizeChanged(); Q_REVISION(1) void httpAcceptLanguageChanged(); - Q_REVISION(3) void spellCheckLanguageChanged(); + Q_REVISION(3) void spellCheckLanguagesChanged(); Q_REVISION(3) void spellCheckEnabledChanged(); void downloadRequested(QQuickWebEngineDownloadItem *download); diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 61f940f15..6ca9954cf 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -1109,7 +1109,7 @@ void QQuickWebEngineViewPrivate::showValidationMessage(const QRect &anchor, cons #endif Q_Q(QQuickWebEngineView); QQuickWebEngineFormValidationMessageRequest *request; - request = new QQuickWebEngineFormValidationMessageRequest(QQuickWebEngineFormValidationMessageRequest::RequestTypeShow, + request = new QQuickWebEngineFormValidationMessageRequest(QQuickWebEngineFormValidationMessageRequest::Show, anchor,mainText,subText); // mark the object for gc by creating temporary jsvalue qmlEngine(q)->newQObject(request); @@ -1122,7 +1122,7 @@ void QQuickWebEngineViewPrivate::hideValidationMessage() { Q_Q(QQuickWebEngineView); QQuickWebEngineFormValidationMessageRequest *request; - request = new QQuickWebEngineFormValidationMessageRequest(QQuickWebEngineFormValidationMessageRequest::RequestTypeHide); + request = new QQuickWebEngineFormValidationMessageRequest(QQuickWebEngineFormValidationMessageRequest::Hide); // mark the object for gc by creating temporary jsvalue qmlEngine(q)->newQObject(request); Q_EMIT q->formValidationMessageRequested(request); @@ -1134,7 +1134,7 @@ void QQuickWebEngineViewPrivate::moveValidationMessage(const QRect &anchor) { Q_Q(QQuickWebEngineView); QQuickWebEngineFormValidationMessageRequest *request; - request = new QQuickWebEngineFormValidationMessageRequest(QQuickWebEngineFormValidationMessageRequest::RequestTypeMove, + request = new QQuickWebEngineFormValidationMessageRequest(QQuickWebEngineFormValidationMessageRequest::Move, anchor); // mark the object for gc by creating temporary jsvalue qmlEngine(q)->newQObject(request); diff --git a/src/webengine/doc/qtwebengine.qdocconf b/src/webengine/doc/qtwebengine.qdocconf index d9b1f1154..fe83b082f 100644 --- a/src/webengine/doc/qtwebengine.qdocconf +++ b/src/webengine/doc/qtwebengine.qdocconf @@ -18,9 +18,9 @@ qhp.QtWebEngine.customFilters.Qt.filterAttributes = qtwebengine $QT_VERSION qhp.QtWebEngine.subprojects = classes qmltypes examples -qhp.QtWebEngine.subprojects.classes.title = C++ Classes -qhp.QtWebEngine.subprojects.classes.indexTitle = Qt WebEngine C++ Classes -qhp.QtWebEngine.subprojects.classes.selectors = class doc:headerfile +qhp.QtWebEngine.subprojects.classes.title = C++ Classes and Namespaces +qhp.QtWebEngine.subprojects.classes.indexTitle = Qt WebEngine C++ Classes and Namespaces +qhp.QtWebEngine.subprojects.classes.selectors = class group:qtwebengine-namespaces doc:headerfile qhp.QtWebEngine.subprojects.classes.sortPages = true qhp.QtWebEngine.subprojects.qmltypes.title = QML Types diff --git a/src/webengine/doc/snippets/qtwebengine_build_snippet.qdoc b/src/webengine/doc/snippets/qtwebengine_build_snippet.qdoc new file mode 100644 index 000000000..248296588 --- /dev/null +++ b/src/webengine/doc/snippets/qtwebengine_build_snippet.qdoc @@ -0,0 +1,8 @@ +//! [0] +QT += webengine +//! [0] + + +//! [1] +#include <QtWebEngine> +//! [1] diff --git a/src/webengine/doc/src/qtwebengine-deploying.qdoc b/src/webengine/doc/src/qtwebengine-deploying.qdoc index b6b91f2e9..25b6d218c 100644 --- a/src/webengine/doc/src/qtwebengine-deploying.qdoc +++ b/src/webengine/doc/src/qtwebengine-deploying.qdoc @@ -30,7 +30,7 @@ \title Deploying Qt WebEngine Applications The way to package and deploy applications varies between operating systems. - For Windows and macOS, \l{The Windows Deployment Tool}{windeployqt} and + For Windows and \macos, \l{The Windows Deployment Tool}{windeployqt} and \l{Deploying Applications on OS X}{macdeployqt} automate the steps to generate a stand-alone application package. @@ -47,7 +47,7 @@ limitations are: \list - \li Qt WebEngine currently supports only Windows, Linux, and macOS. + \li Qt WebEngine currently supports only Windows, Linux, and \macos. \li On Windows, Qt WebEngine only supports Windows Vista or newer as target platform. Due to use of newer API in Chromium, Windows XP is @@ -102,7 +102,7 @@ For Qt installations, this is \c QTDIR/libexec (Linux) or \c QTDIR\bin (Windows). The path can be changed by defining a \c qt.conf file, for example. Alternatively, an executable path can be set as a value of the - \c QTWEBENGINEPROCESS_PATH environment variable. On macOS, Qt WebEngine + \c QTWEBENGINEPROCESS_PATH environment variable. On \macos, Qt WebEngine looks for the executable in \c .app/Helpers/QtWebEngineProcess. \section2 Deploying Resources @@ -128,7 +128,7 @@ \list \li On Linux and Windows: the \c resources directory in the directory specified by QLibraryInfo::location(QLibraryInfo::DataPath) - \li On macOS: \c .app/Content/Resources + \li On \macos: \c .app/Content/Resources \endlist \section2 Translations @@ -136,7 +136,7 @@ Locale data (such as \c en-US.pak) is searched form the following locations: \list - \li On macOS: \c .app/Content/Resources + \li On \macos: \c .app/Content/Resources \li On Linux and Windows: \c qtwebengine_locales directory in the directory specified by QLibraryInfo::location(QLibraryInfo::TranslationsPath) diff --git a/src/webengine/doc/src/qtwebengine-features.qdoc b/src/webengine/doc/src/qtwebengine-features.qdoc index 5ba3f23b8..647f1030b 100644 --- a/src/webengine/doc/src/qtwebengine-features.qdoc +++ b/src/webengine/doc/src/qtwebengine-features.qdoc @@ -222,6 +222,7 @@ \li Linux \code /usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so + /usr/lib/adobe-flashplugin/libpepflashplayer.so /usr/lib/PepperFlash/libpepflashplayer.so /usr/lib64/chromium/PepperFlash/libpepflashplayer.so \endcode @@ -292,9 +293,9 @@ {WebEngineProfile.spellCheckEnabled} property in Qt Quick applications. The current language used for spellchecking is defined per profile, and can - be set using the QWebEngineProfile::setSpellCheckLanguage() method or the - \l {QQuickWebEngineProfile::spellCheckLanguage} - {WebEngineProfile.spellCheckLanguage} property. + be set using the QWebEngineProfile::setSpellCheckLanguages() method or the + \l {QQuickWebEngineProfile::spellCheckLanguages} + {WebEngineProfile.spellCheckLanguages} property. This feature can be tested by building and running the \l{WebEngine Widgets Spellchecker Example}{Spellchecker Example}. diff --git a/src/webengine/doc/src/qtwebengine-index.qdoc b/src/webengine/doc/src/qtwebengine-index.qdoc index c4be591ff..bd6cc9a32 100644 --- a/src/webengine/doc/src/qtwebengine-index.qdoc +++ b/src/webengine/doc/src/qtwebengine-index.qdoc @@ -28,7 +28,6 @@ /*! \page qtwebengine-index.html \title Qt WebEngine - \ingroup modules \brief Provides functionality for rendering regions of dynamic web content. diff --git a/src/webengine/doc/src/qtwebengine-module.qdoc b/src/webengine/doc/src/qtwebengine-module.qdoc new file mode 100644 index 000000000..97657f6a9 --- /dev/null +++ b/src/webengine/doc/src/qtwebengine-module.qdoc @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \module QtWebEngine + \title Qt WebEngine C++ Classes + \brief Exposes C++ functionality to Qt Quick. + \ingroup modules + + The Qt WebEngine module exposes C++ functionality to Qt Quick. + + To include the definitions of the module's classes, use the + following directive: + + \snippet qtwebengine_build_snippet.qdoc 1 + + To link against the module, add the following to your qmake project file: + + \snippet qtwebengine_build_snippet.qdoc 0 +*/ diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc index d5b7d40a0..6995be2fa 100644 --- a/src/webengine/doc/src/qtwebengine-overview.qdoc +++ b/src/webengine/doc/src/qtwebengine-overview.qdoc @@ -197,9 +197,11 @@ \section1 Proxy Support - If QNetworkProxy::applicationProxy is set, it will also be used for Qt WebEngine. Otherwise, - Qt WebEngine automatically picks up the proxy configuration from OS X and Windows. On Linux, - it acknowledges settings from KDE and Gnome. + Qt WebEngine uses the proxy settings from \l{Qt Network}. If + QNetworkProxy::applicationProxy is set, it will also be used for Qt WebEngine, and if + QNetworkProxy::usesSystemConfiguration() is enabled, the proxy settings are automatically + retrieved from the system. Settings from an installed QNetworkProxyFactory will be ignored + though. If a proxy requires authentication, QWebEnginePage::proxyAuthenticationRequired is emitted. For Qt Quick, a dialog is shown. @@ -248,7 +250,7 @@ \section1 Platform Notes - Qt WebEngine currently supports only Windows, Linux, and OS X. Due to Chromium build + Qt WebEngine currently supports only Windows, Linux, and \macos. Due to Chromium build requirements it also often requires a newer compiler than the rest of Qt. See \l{Qt WebEngine Platform Notes} for further details. diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc index 9a59f1f1f..c5ebe0f06 100644 --- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc +++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc @@ -41,7 +41,7 @@ \list \li \l{Qt for Windows - Requirements} \li \l{Qt for X11 Requirements} - \li \l{Qt for OS X - Requirements} + \li \l{Qt for macOS - Requirements} \endlist In addition, the following tools are required for building the \l {Qt WebEngine} module: @@ -50,7 +50,7 @@ \li \l {All Platforms} \li \l {Windows} \li \l {Linux} - \li \l {OS X} + \li \l {macOS} \endlist The tests for skipping the Qt WebEngine build are located in the @@ -99,22 +99,22 @@ Further, development packages for \c khr and \c libcap need to be installed. - \section2 OS X + \section2 \macos - On OS X, the following are required: + On \macos, the following are required: \list - \li OS X 10.10 or later - \li Xcode 6.3 or later - \li OS X 10.10 SDK or later + \li \macos 10.9 or later + \li Xcode 5.1 or later + \li \macos 10.10 SDK or later \endlist - \note Qt WebEngine cannot be built for the 32-bit mode of OS X (using the + \note Qt WebEngine cannot be built for the 32-bit mode of \macos (using the \c macx-clang-32 \c mkspec). \section1 Mac App Store Compatibility - By default, Qt WebEngine uses private OS X API, which might cause an application to be + By default, Qt WebEngine uses private \macos API, which might cause an application to be rejected when submitted to the Mac App Store. To configure Qt WebEngine not to use these API calls, Qt WebEngine has to be recompiled: @@ -125,10 +125,10 @@ However, this will cause some behavioral changes, such as: \list - \li The OS X Kill Ring functionality will no longer work (emacs-like copy pasting). + \li The \macos Kill Ring functionality will no longer work (emacs-like copy pasting). \li Certain Chromium sandboxing cleanup is not done. \li Text areas will be painted with a different style. - \li Text fields might be painted with a different style on Mountain Lion (OS X 10.8). + \li Text fields might be painted with a different style on Mountain Lion (\macos 10.8). \endlist \section1 Default QSurfaceFormat OpenGL Profile Support @@ -137,7 +137,7 @@ before the application instance is declared, to make sure that all created OpenGL contexts use the same OpenGL profile. - On OS X, if the default QSurfaceFormat is set after the application instance, the application + On \macos, if the default QSurfaceFormat is set after the application instance, the application will exit with qFatal(), and print a message that the default QSurfaceFormat should be set before the application instance. */ diff --git a/src/webengine/doc/src/qwebengine-licensing.qdoc b/src/webengine/doc/src/qwebengine-licensing.qdoc index c31bd9dac..a7642df5a 100644 --- a/src/webengine/doc/src/qwebengine-licensing.qdoc +++ b/src/webengine/doc/src/qwebengine-licensing.qdoc @@ -17,7 +17,7 @@ Third party licenses included in the sources are: /*! \contentspage qtwebengine-licensing.html -\page qtwebengine-3rdparty-chromium-global.html +\page qtwebengine-3rdparty-chromium-global.html attribution \ingroup qtwebengine-licensing \title Chromium License \brief BSD diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp index e9312a92a..0fd2087d4 100644 --- a/src/webengine/plugin/plugin.cpp +++ b/src/webengine/plugin/plugin.cpp @@ -66,7 +66,7 @@ class QtWebEnginePlugin : public QQmlExtensionPlugin Q_OBJECT Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: - virtual void initializeEngine(QQmlEngine *engine, const char *uri) + virtual void initializeEngine(QQmlEngine *engine, const char *uri) Q_DECL_OVERRIDE { Q_UNUSED(uri); engine->addImageProvider(QQuickWebEngineFaviconProvider::identifier(), new QQuickWebEngineFaviconProvider); @@ -77,8 +77,8 @@ public: Q_ASSERT(QLatin1String(uri) == QLatin1String("QtWebEngine")); qmlRegisterType<QQuickWebEngineView>(uri, 1, 0, "WebEngineView"); - qmlRegisterUncreatableType<QQuickWebEngineLoadRequest>(uri, 1, 0, "WebEngineLoadRequest", tr("Cannot create separate instance of WebEngineLoadRequest")); - qmlRegisterUncreatableType<QQuickWebEngineNavigationRequest>(uri, 1, 0, "WebEngineNavigationRequest", tr("Cannot create separate instance of WebEngineNavigationRequest")); + qmlRegisterUncreatableType<QQuickWebEngineLoadRequest>(uri, 1, 0, "WebEngineLoadRequest", msgUncreatableType("WebEngineLoadRequest")); + qmlRegisterUncreatableType<QQuickWebEngineNavigationRequest>(uri, 1, 0, "WebEngineNavigationRequest", msgUncreatableType("WebEngineNavigationRequest")); qmlRegisterType<QQuickWebEngineView, 1>(uri, 1, 1, "WebEngineView"); qmlRegisterType<QQuickWebEngineView, 2>(uri, 1, 2, "WebEngineView"); @@ -89,7 +89,7 @@ public: qmlRegisterType<QQuickWebEngineProfile, 2>(uri, 1, 3, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineProfile, 3>(uri, 1, 4, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineScript>(uri, 1, 1, "WebEngineScript"); - qmlRegisterUncreatableType<QQuickWebEngineCertificateError>(uri, 1, 1, "WebEngineCertificateError", tr("Cannot create separate instance of WebEngineCertificateError")); + qmlRegisterUncreatableType<QQuickWebEngineCertificateError>(uri, 1, 1, "WebEngineCertificateError", msgUncreatableType("WebEngineCertificateError")); qmlRegisterUncreatableType<QQuickWebEngineDownloadItem>(uri, 1, 1, "WebEngineDownloadItem", tr("Cannot create a separate instance of WebEngineDownloadItem")); qmlRegisterUncreatableType<QQuickWebEngineDownloadItem, 1>(uri, 1, 2, "WebEngineDownloadItem", @@ -98,7 +98,7 @@ public: tr("Cannot create a separate instance of WebEngineDownloadItem")); qmlRegisterUncreatableType<QQuickWebEngineDownloadItem, 3>(uri, 1, 4, "WebEngineDownloadItem", tr("Cannot create a separate instance of WebEngineDownloadItem")); - qmlRegisterUncreatableType<QQuickWebEngineNewViewRequest>(uri, 1, 1, "WebEngineNewViewRequest", tr("Cannot create separate instance of WebEngineNewViewRequest")); + qmlRegisterUncreatableType<QQuickWebEngineNewViewRequest>(uri, 1, 1, "WebEngineNewViewRequest", msgUncreatableType("WebEngineNewViewRequest")); qmlRegisterUncreatableType<QQuickWebEngineSettings>(uri, 1, 1, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings")); qmlRegisterUncreatableType<QQuickWebEngineSettings, 1>(uri, 1, 2, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings")); qmlRegisterUncreatableType<QQuickWebEngineSettings, 2>(uri, 1, 3, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings")); @@ -112,21 +112,27 @@ public: tr("Cannot create a separate instance of FullScreenRequest")); qmlRegisterUncreatableType<QQuickWebEngineContextMenuRequest>(uri, 1, 4, "ContextMenuRequest", - tr("Cannot create separate instance of ContextMenuRequest")); + msgUncreatableType("ContextMenuRequest")); qmlRegisterUncreatableType<QQuickWebEngineAuthenticationDialogRequest>(uri, 1, 4, "AuthenticationDialogRequest", - tr("Cannot create separate instance of AuthenticationDialogRequest")); + msgUncreatableType("AuthenticationDialogRequest")); qmlRegisterUncreatableType<QQuickWebEngineJavaScriptDialogRequest>(uri, 1, 4, "JavaScriptDialogRequest", - tr("Cannot create separate instance of JavaScriptDialogRequest")); + msgUncreatableType("JavaScriptDialogRequest")); qmlRegisterUncreatableType<QQuickWebEngineColorDialogRequest>(uri, 1, 4, "ColorDialogRequest", - tr("Cannot create separate instance of ColorDialogRequest")); + msgUncreatableType("ColorDialogRequest")); qmlRegisterUncreatableType<QQuickWebEngineFileDialogRequest>(uri, 1, 4, "FileDialogRequest", - tr("Cannot create separate instance of FileDialogRequest")); + msgUncreatableType("FileDialogRequest")); qmlRegisterUncreatableType<QQuickWebEngineFormValidationMessageRequest>(uri, 1, 4, "FormValidationMessageRequest", - tr("Cannot create separate instance of FormValidationMessageRequest")); + msgUncreatableType("FormValidationMessageRequest")); // For now (1.x import), the latest revision matches the minor version of the import. qmlRegisterRevision<QQuickWebEngineView, LATEST_WEBENGINEVIEW_REVISION>(uri, 1, LATEST_WEBENGINEVIEW_REVISION); } + +private: + static QString msgUncreatableType(const char *className) + { + return tr("Cannot create separate instance of %1").arg(QLatin1String(className)); + } }; QT_END_NAMESPACE diff --git a/src/webengine/plugin/plugins.qmltypes b/src/webengine/plugin/plugins.qmltypes index c8aaaf420..48a572866 100644 --- a/src/webengine/plugin/plugins.qmltypes +++ b/src/webengine/plugin/plugins.qmltypes @@ -198,9 +198,9 @@ Module { Enum { name: "RequestType" values: { - "RequestTypeShow": 0, - "RequestTypeHide": 1, - "RequestTypeMove": 2 + "Show": 0, + "Hide": 1, + "Move": 2 } } Property { name: "anchor"; type: "QRect"; isReadonly: true } @@ -359,10 +359,10 @@ Module { Property { name: "httpAcceptLanguage"; revision: 1; type: "string" } Property { name: "persistentCookiesPolicy"; type: "PersistentCookiesPolicy" } Property { name: "httpCacheMaximumSize"; type: "int" } - Property { name: "spellCheckLanguage"; revision: 3; type: "string" } + Property { name: "spellCheckLanguages"; revision: 3; type: "QStringList" } Property { name: "spellCheckEnabled"; revision: 3; type: "bool" } Signal { name: "httpAcceptLanguageChanged"; revision: 1 } - Signal { name: "spellCheckLanguageChanged"; revision: 3 } + Signal { name: "spellCheckLanguagesChanged"; revision: 3 } Signal { name: "spellCheckEnabledChanged"; revision: 3 } Signal { name: "downloadRequested" diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp index 6896b850d..a37484023 100644 --- a/src/webengine/ui_delegates_manager.cpp +++ b/src/webengine/ui_delegates_manager.cpp @@ -523,7 +523,8 @@ void UIDelegatesManager::hideMessageBubble() void UIDelegatesManager::moveMessageBubble(const QRect &anchor) { - Q_ASSERT(!m_messageBubbleItem.isNull()); + if (m_messageBubbleItem.isNull()) + return; QQmlProperty(m_messageBubbleItem.data(), QStringLiteral("x")).write(anchor.x()); QQmlProperty(m_messageBubbleItem.data(), QStringLiteral("y")).write(anchor.y() + anchor.size().height()); diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro index 6b2285c85..99b9c4e6f 100644 --- a/src/webengine/webengine.pro +++ b/src/webengine/webengine.pro @@ -61,7 +61,7 @@ isQMLTestSupportApiEnabled() { DEFINES += ENABLE_QML_TESTSUPPORT_API } -!contains(WEBENGINE_CONFIG, no_spellcheck) { +contains(WEBENGINE_CONFIG, use_spellchecker) { DEFINES += ENABLE_SPELLCHECK } diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 1004b3e92..ca160c362 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -333,6 +333,11 @@ void QWebEnginePagePrivate::adoptNewWindowImpl(QWebEnginePage *newPage, if (!initialGeometry.isEmpty()) emit newPage->geometryChangeRequested(initialGeometry); + // If the constructor of the QWebEnginePage descendant set a web channel, + // set it on the new adapter. + newWebContents->setWebChannel(newPage->d_func()->webChannel + , newPage->d_func()->webChannelWorldId); + // Page has finished the adoption process. newPage->d_func()->m_isBeingAdopted = false; } diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp index a400b5792..886a7207e 100644 --- a/src/webenginewidgets/api/qwebengineprofile.cpp +++ b/src/webenginewidgets/api/qwebengineprofile.cpp @@ -98,8 +98,8 @@ using QtWebEngineCore::BrowserContextAdapter; QWebEngineUrlSchemeHandler::requestStarted() as QWebEngineUrlRequestJob objects. Spellchecking HTML form fields can be enabled per profile by using the setSpellCheckEnabled() - method and the current language used for spellchecking can be set by using the - setSpellCheckLanguage() method. + method and the current languages used for spellchecking can be set by using the + setSpellCheckLanguages() method. */ @@ -565,39 +565,59 @@ QWebEngineProfile *QWebEngineProfile::defaultProfile() /*! \since 5.8 - Sets the current \a language for the spell checker. - The language should match the name of the \c .bdic dictionary. - For example, the \a language \c en-US will load the \c en-US.bdic + Sets the current list of \a languages for the spell checker. + Each language should match the name of the \c .bdic dictionary. + For example, the language \c en-US will load the \c en-US.bdic dictionary file. - The web engine checks for the \c qtwebengine_dictionaries subdirectory - first in the local directory and if it is not found in the Qt - installation directory: + Qt WebEngine checks for the \c qtwebengine_dictionaries subdirectory + first in the local directory and if it is not found, in the Qt + installation directory. + + On macOS, depending on how Qt WebEngine is configured at build time, there are two possibilities + how spellchecking data is found: + + \list + \li Hunspell dictionaries (default) - .bdic dictionaries are used, just like on other + platforms + \li Native dictionaries - the macOS spellchecking APIs are used (which means the results + will depend on the installed OS dictionaries) + \endlist + + Thus, in the macOS Hunspell case, Qt WebEngine will look in the \e qtwebengine_dictionaries + subdirectory located inside the application bundle \c Resources directory, and also in the + \c Resources directory located inside the Qt framework bundle. + + To summarize, in case of Hunspell usage, the following paths are considered: \list \li QCoreApplication::applicationDirPath()/qtwebengine_dictionaries + or QCoreApplication::applicationDirPath()/../Contents/Resources/qtwebengine_dictionaries + (on macOS) \li [QLibraryInfo::DataPath]/qtwebengine_dictionaries + or path/to/QtWebEngineCore.framework/Resources/qtwebengine_dictionaries (Qt framework + bundle on macOS) \endlist For more information about how to compile \c .bdic dictionaries, see the \l{WebEngine Widgets Spellchecker Example}{Spellchecker Example}. */ -void QWebEngineProfile::setSpellCheckLanguage(const QString &language) +void QWebEngineProfile::setSpellCheckLanguages(const QStringList &languages) { Q_D(QWebEngineProfile); - d->browserContext()->setSpellCheckLanguage(language); + d->browserContext()->setSpellCheckLanguages(languages); } /*! \since 5.8 - Returns the language used by the spell checker. + Returns the list of languages used by the spell checker. */ -QString QWebEngineProfile::spellCheckLanguage() const +QStringList QWebEngineProfile::spellCheckLanguages() const { const Q_D(QWebEngineProfile); - return d->browserContext()->spellCheckLanguage(); + return d->browserContext()->spellCheckLanguages(); } /*! diff --git a/src/webenginewidgets/api/qwebengineprofile.h b/src/webenginewidgets/api/qwebengineprofile.h index 704414bcf..1ce4bfe17 100644 --- a/src/webenginewidgets/api/qwebengineprofile.h +++ b/src/webenginewidgets/api/qwebengineprofile.h @@ -121,8 +121,8 @@ public: void clearHttpCache(); - void setSpellCheckLanguage(const QString &language); - QString spellCheckLanguage() const; + void setSpellCheckLanguages(const QStringList &languages); + QStringList spellCheckLanguages() const; void setSpellCheckEnabled(bool enabled); bool isSpellCheckEnabled() const; diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp index 6171391e3..8b4053e73 100644 --- a/src/webenginewidgets/api/qwebengineview.cpp +++ b/src/webenginewidgets/api/qwebengineview.cpp @@ -107,6 +107,7 @@ static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *obje QWebEngineViewPrivate::QWebEngineViewPrivate() : page(0) , m_pendingContextMenuEvent(false) + , m_dragEntered(false) { #ifndef QT_NO_ACCESSIBILITY QAccessible::installFactory(&webAccessibleFactory); @@ -350,7 +351,10 @@ void QWebEngineView::dragEnterEvent(QDragEnterEvent *e) { Q_D(QWebEngineView); e->accept(); + if (d->m_dragEntered) + d->page->d_ptr->adapter->leaveDrag(); d->page->d_ptr->adapter->enterDrag(e, mapToGlobal(e->pos())); + d->m_dragEntered = true; } /*! @@ -359,8 +363,11 @@ void QWebEngineView::dragEnterEvent(QDragEnterEvent *e) void QWebEngineView::dragLeaveEvent(QDragLeaveEvent *e) { Q_D(QWebEngineView); + if (!d->m_dragEntered) + return; e->accept(); d->page->d_ptr->adapter->leaveDrag(); + d->m_dragEntered = false; } /*! @@ -369,6 +376,8 @@ void QWebEngineView::dragLeaveEvent(QDragLeaveEvent *e) void QWebEngineView::dragMoveEvent(QDragMoveEvent *e) { Q_D(QWebEngineView); + if (!d->m_dragEntered) + return; QtWebEngineCore::WebContentsAdapter *adapter = d->page->d_ptr->adapter.data(); Qt::DropAction dropAction = adapter->updateDragPosition(e, mapToGlobal(e->pos())); if (Qt::IgnoreAction == dropAction) { @@ -385,8 +394,11 @@ void QWebEngineView::dragMoveEvent(QDragMoveEvent *e) void QWebEngineView::dropEvent(QDropEvent *e) { Q_D(QWebEngineView); + if (!d->m_dragEntered) + return; e->accept(); d->page->d_ptr->adapter->endDragging(e->pos(), mapToGlobal(e->pos())); + d->m_dragEntered = false; } #ifndef QT_NO_ACCESSIBILITY diff --git a/src/webenginewidgets/api/qwebengineview_p.h b/src/webenginewidgets/api/qwebengineview_p.h index b98c553f4..45b3e266e 100644 --- a/src/webenginewidgets/api/qwebengineview_p.h +++ b/src/webenginewidgets/api/qwebengineview_p.h @@ -71,6 +71,7 @@ public: QWebEnginePage *page; bool m_pendingContextMenuEvent; + bool m_dragEntered; }; #ifndef QT_NO_ACCESSIBILITY diff --git a/src/webenginewidgets/doc/snippets/qtwebengine_build_snippet.qdoc b/src/webenginewidgets/doc/snippets/qtwebenginewidgets_build_snippet.qdoc index dcdd82e04..dcdd82e04 100644 --- a/src/webenginewidgets/doc/snippets/qtwebengine_build_snippet.qdoc +++ b/src/webenginewidgets/doc/snippets/qtwebenginewidgets_build_snippet.qdoc diff --git a/src/webenginewidgets/doc/src/qtwebenginewidgets-index.qdoc b/src/webenginewidgets/doc/src/qtwebenginewidgets-index.qdoc index 59d7bc5d1..abfd17ce3 100644 --- a/src/webenginewidgets/doc/src/qtwebenginewidgets-index.qdoc +++ b/src/webenginewidgets/doc/src/qtwebenginewidgets-index.qdoc @@ -28,7 +28,6 @@ /*! \page qtwebenginewidgets-index.html \title Qt WebEngine Widgets - \ingroup modules \brief Provides a web browser engine as well as C++ classes to render web content and interact with it. diff --git a/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc b/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc index d0f2fd930..959f96b10 100644 --- a/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc +++ b/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc @@ -40,9 +40,9 @@ To include the definitions of the module's classes, use the following directive: - \snippet qtwebengine_build_snippet.qdoc 1 + \snippet qtwebenginewidgets_build_snippet.qdoc 1 To link against the module, add the following to your qmake project file: - \snippet qtwebengine_build_snippet.qdoc 0 + \snippet qtwebenginewidgets_build_snippet.qdoc 0 */ diff --git a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc index 69bac36c8..07afd6501 100644 --- a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc @@ -164,12 +164,12 @@ /*! \fn void QWebEngineSettings::setFontSize(FontSize type, int size) - Sets the font size for \a type to \a size. + Sets the font size for \a type to \a size in pixels. */ /*! \fn int QWebEngineSettings::fontSize(FontSize type) const - Returns the default font size for \a type. + Returns the default font size for \a type in pixels. */ /*! 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 43011de0e..eb3a3931a 100644 --- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp +++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp @@ -55,6 +55,7 @@ #include <QSGSimpleRectNode> #include <QSGSimpleTextureNode> #endif +#include <private/qwidget_p.h> namespace QtWebEngineCore { @@ -392,10 +393,22 @@ bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event) return true; } break; + case QEvent::DragEnter: + case QEvent::DragLeave: + case QEvent::DragMove: + case QEvent::Drop: + // Let the parent handle these events. + return false; default: break; } + QEvent::Type type = event->type(); + if (type == QEvent::FocusIn) { + QWidgetPrivate *d = QWidgetPrivate::get(this); + d->updateWidgetTransform(event); + } + if (event->type() == QEvent::MouseButtonDblClick) { // QWidget keeps the Qt4 behavior where the DblClick event would replace the Press event. // QtQuick is different by sending both the Press and DblClick events for the second press diff --git a/src/webenginewidgets/webenginewidgets.pro b/src/webenginewidgets/webenginewidgets.pro index f1bb86df4..64e475422 100644 --- a/src/webenginewidgets/webenginewidgets.pro +++ b/src/webenginewidgets/webenginewidgets.pro @@ -4,7 +4,7 @@ TARGET = QtWebEngineWidgets DEFINES += QT_BUILD_WEBENGINEWIDGETS_LIB QT += webenginecore widgets network quick -QT_PRIVATE += quick-private gui-private core-private quickwidgets +QT_PRIVATE += quick-private gui-private core-private widgets-private quickwidgets INCLUDEPATH += $$PWD api ../core ../core/api ../webengine/api @@ -48,7 +48,7 @@ HEADERS = \ DEFINES += QT_UI_DELEGATES } -!contains(WEBENGINE_CONFIG, no_spellcheck) { +contains(WEBENGINE_CONFIG, use_spellchecker) { DEFINES += ENABLE_SPELLCHECK } |