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/core | |
parent | b4f8480fd41a806abe04e8eb2a4c416b2eff53c6 (diff) | |
parent | ecfb3ba8a7eb116c838a1acd5b82ca59ce76b082 (diff) |
Merge remote-tracking branch 'origin/5.8' into dev
Change-Id: Ib2a1eb4dfae2fb5a98066d3d0f8f09f4e1d61d3f
Diffstat (limited to 'src/core')
34 files changed, 292 insertions, 125 deletions
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 |