summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2016-09-09 17:09:42 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2016-10-17 16:38:34 +0000
commit7b7c9cb4183651b496501e89deb497490199b320 (patch)
tree8f75ba32ab826cfd5c1d689c24ca88f20520c50f
parent1eb814230515ffb3417e0ac9533fc24847c1ebb9 (diff)
Fix spellchecking for macOS
The change fixes spellchecking to work on macOS. A new WebEngine configure option is available to allow spellchecking on macOS to use either Hunspell like the other platforms, or the native spellchecker that comes with the OS. The default is to use Hunspell. Task-number: QTBUG-53135 Change-Id: I3e45b2e0d728b1bf2659c35f3d0a042b0ecd6239 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r--examples/examples.pro8
-rw-r--r--examples/webenginewidgets/spellchecker/doc/src/spellchecker.qdoc21
-rw-r--r--examples/webenginewidgets/spellchecker/spellchecker.pro22
-rw-r--r--src/core/chrome_qt.gyp2
-rw-r--r--src/core/content_browser_client_qt.cpp7
-rw-r--r--src/core/gyp_run.pro10
-rw-r--r--src/core/web_engine_library_info.cpp70
-rw-r--r--src/src.pro3
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp26
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp26
-rw-r--r--tools/qmake/mkspecs/features/configure.prf5
11 files changed, 170 insertions, 30 deletions
diff --git a/examples/examples.pro b/examples/examples.pro
index f15007e83..0e222de73 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -15,8 +15,12 @@ qtHaveModule(webenginewidgets) {
webenginewidgets/markdowneditor \
webenginewidgets/simplebrowser
- !contains(WEBENGINE_CONFIG, no_spellcheck):!osx:!cross_compile {
- SUBDIRS += webenginewidgets/spellchecker
+ !contains(WEBENGINE_CONFIG, no_spellcheck):!cross_compile {
+ !contains(WEBENGINE_CONFIG, use_native_spellchecker) {
+ SUBDIRS += webenginewidgets/spellchecker
+ } else {
+ message("Spellcheck example will not be built because it depends on usage of Hunspell dictionaries.")
+ }
}
}
diff --git a/examples/webenginewidgets/spellchecker/doc/src/spellchecker.qdoc b/examples/webenginewidgets/spellchecker/doc/src/spellchecker.qdoc
index d5b972b93..b0240cd4d 100644
--- a/examples/webenginewidgets/spellchecker/doc/src/spellchecker.qdoc
+++ b/examples/webenginewidgets/spellchecker/doc/src/spellchecker.qdoc
@@ -41,12 +41,12 @@
\section1 Dictionaries
To be able to check the spelling, we need to provide the spellchecker with
- dictionaries. In this example, we want to support the English and German
- languages.
+ dictionaries. The Qt WebEngine spellchecker supports dictionaries provided by the
+ \l {Hunspell project} on all platforms and native dictionaries provided by macOS.
+ In this example, we want to support the English and German languages.
- The Qt WebEngine spellchecker supports dictionaries from the
- \l{Hunspell project}, but they have to be compiled into a special binary
- format. A Hunspell dictionary consists of two files:
+ For Hunspell dictionaries to be supported they have to be compiled into a special binary format.
+ A Hunspell dictionary consists of two files:
\list
@@ -78,7 +78,12 @@
When a specific spellchecking language is requested, Qt WebEngine will try
to load the already compiled matching \c .bdic file first from
\e qtwebengine_dictionaries directories relative to the executable,
- then it will look in \c QT_INSTALL_PREFIX/qtwebengines_dictionaries.
+ then it will look in \c QT_INSTALL_PREFIX/qtwebengine_dictionaries.
+
+ On macOS, because this example was configured to use Hunspell dictionaries, Qt WebEngine will
+ look in the \e qtwebengine_dictionaries directory located inside the application bundle
+ \c Resources directory, and also in the \c Resources directory located inside the
+ Qt framework bundle.
We specify the QMAKE_EXTRA_COMPILERS parameter in the project file to add a
conversion step to the build process:
@@ -87,11 +92,11 @@
\skipto CONVERT_TOOL
\printuntil QMAKE_EXTRA_COMPILERS
- To set up a dictionary, we run \c qwebengine_convert_dic passing the
+ To set up a dictionary, we run \c qwebengine_convert_dict passing the
file path of the dictionary \c dic and \c bdic files. The \c aff file and
optional \c delta file are also picked up by the \c convert process.
The output \c bdic file is placed into the \e qtwebengine_dictionaries local
- directory, which the application binary will run from.
+ directory (or Resources directory), which the application binary will run from.
\section1 Setting the Spellchecker
diff --git a/examples/webenginewidgets/spellchecker/spellchecker.pro b/examples/webenginewidgets/spellchecker/spellchecker.pro
index c7bee6584..c6031a36d 100644
--- a/examples/webenginewidgets/spellchecker/spellchecker.pro
+++ b/examples/webenginewidgets/spellchecker/spellchecker.pro
@@ -3,6 +3,10 @@ TARGET = spellchecker
QT += webenginewidgets
CONFIG += c++11
+contains(WEBENGINE_CONFIG, use_native_spellchecker) {
+ error("Spellcheck example can not be built when using native OS dictionaries.")
+}
+
HEADERS += \
webview.h
@@ -33,7 +37,11 @@ debug_and_release {
DICTIONARIES_DIR = qtwebengine_dictionaries
}
-dict.files = $$PWD/dict/en/en-US.dic $$PWD/dict/de/de-DE.dic
+dict_base_paths = en/en-US de/de-DE
+for (base_path, dict_base_paths) {
+ dict.files += $$PWD/dict/$${base_path}.dic
+}
+
dictoolbuild.input = dict.files
dictoolbuild.output = $${DICTIONARIES_DIR}/${QMAKE_FILE_BASE}.bdic
dictoolbuild.depends = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.aff
@@ -41,3 +49,15 @@ dictoolbuild.commands = $${CONVERT_TOOL} ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
dictoolbuild.name = Build ${QMAKE_FILE_IN_BASE}
dictoolbuild.CONFIG = no_link target_predeps
QMAKE_EXTRA_COMPILERS += dictoolbuild
+
+# When the example is compiled as a bundle, WebEngine expects to find the dictionaries in
+# bundle.app/Contents/Resources/qtwebengine_dictionaries
+macos:app_bundle {
+ for (base_path, dict_base_paths) {
+ base_path_splitted = $$split(base_path, /)
+ base_name = $$last(base_path_splitted)
+ binary_dict_files.files += $${DICTIONARIES_DIR}/$${base_name}.bdic
+ }
+ binary_dict_files.path = Contents/Resources/$$DICTIONARIES_DIR
+ QMAKE_BUNDLE_DATA += binary_dict_files
+}
diff --git a/src/core/chrome_qt.gyp b/src/core/chrome_qt.gyp
index 3fa2625a8..89f1fe188 100644
--- a/src/core/chrome_qt.gyp
+++ b/src/core/chrome_qt.gyp
@@ -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/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 64964dc09..a57c3b00f 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -44,6 +44,9 @@
#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"
@@ -377,8 +380,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)
diff --git a/src/core/gyp_run.pro b/src/core/gyp_run.pro
index 89b751c4a..1c62c0cfd 100644
--- a/src/core/gyp_run.pro
+++ b/src/core/gyp_run.pro
@@ -124,10 +124,16 @@ contains(WEBENGINE_CONFIG, reduce_binary_size): GYP_CONFIG += release_optimize=s
contains(WEBENGINE_CONFIG, no_spellcheck): {
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/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..495263846 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, no_spellcheck):!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/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index 1ca97adea..6a4846ddf 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -632,13 +632,33 @@ QQuickWebEngineProfile *QQuickWebEngineProfile::defaultProfile()
For example, the \a 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
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index a400b5792..bd41a5126 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -570,13 +570,33 @@ QWebEngineProfile *QWebEngineProfile::defaultProfile()
For example, the \a 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
diff --git a/tools/qmake/mkspecs/features/configure.prf b/tools/qmake/mkspecs/features/configure.prf
index 89fa3a242..ee0cce1b2 100644
--- a/tools/qmake/mkspecs/features/configure.prf
+++ b/tools/qmake/mkspecs/features/configure.prf
@@ -123,6 +123,11 @@ defineTest(finalizeConfigure) {
} else {
log("AppStore Compliant ............... Not enabled (Default, enable with WEBENGINE_CONFIG+=use_appstore_compliant_code)$${EOL}")
}
+ use?(native_spellchecker) {
+ log("Native Spellchecker .............. Enabled$${EOL}")
+ } else {
+ log("Native Spellchecker .............. Not enabled (Default, enable with WEBENGINE_CONFIG+=use_native_spellchecker)$${EOL}")
+ }
!isMinOSXSDKVersion(10, 10, 3) {
log("Force Touch API usage ............ Not enabled (Because the OS X SDK version to be used \"$${WEBENGINE_OSX_SDK_PRODUCT_VERSION}\" is lower than the required \"10.10.3\")$${EOL}")
}