summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-02-01 20:50:41 +0100
committerOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-02-01 20:58:12 +0100
commitb5d7ec9226eee41d9c3516bf51dc48c283e8b13e (patch)
tree994d2f09fd2106efed07e007becffed6e56a584c
parent3c4c080e46a8fa229d7e1fdaee82f750b3558aa0 (diff)
parent2313a580c0e3f0636a12697ba4b872bfdccbcf7f (diff)
Merge dev into 5.9
-rw-r--r--configure.json29
-rw-r--r--configure.pri9
-rw-r--r--examples/webenginewidgets/spellchecker/webview.cpp4
-rw-r--r--src/core/config/common.pri100
-rw-r--r--src/core/config/desktop_linux.pri36
-rw-r--r--src/core/config/embedded_linux.pri1
-rw-r--r--src/core/config/linux.pri38
-rw-r--r--src/core/config/mac_osx.pri55
-rw-r--r--src/core/content_browser_client_qt.cpp2
-rw-r--r--src/core/core.pro29
-rw-r--r--src/core/core_generator.pro10
-rw-r--r--src/core/core_gn_config.pri6
-rw-r--r--src/core/core_module.pro39
-rw-r--r--src/core/gn_run.pro34
-rw-r--r--src/core/gyp_run.pro2
-rw-r--r--src/core/qtwebengine.gni47
-rw-r--r--src/core/qtwebengine.gypi5
-rw-r--r--src/core/qtwebengine_resources.gni86
-rw-r--r--src/core/qtwebengine_sources.gni128
-rw-r--r--src/core/render_widget_host_view_qt.cpp66
-rw-r--r--src/core/render_widget_host_view_qt.h2
-rw-r--r--src/core/render_widget_host_view_qt_delegate.h1
-rw-r--r--src/core/web_contents_adapter.cpp98
-rw-r--r--src/core/web_contents_adapter.h2
-rw-r--r--src/core/web_contents_adapter_p.h6
-rw-r--r--src/core/web_contents_view_qt.cpp13
-rw-r--r--src/core/web_event_factory.cpp9
-rw-r--r--src/src.pro51
-rw-r--r--src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro27
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp63
-rw-r--r--src/webengine/api/qquickwebengineprofile.h5
-rw-r--r--src/webengine/api/qquickwebengineprofile_p.h7
-rw-r--r--src/webengine/api/qquickwebenginescript.cpp171
-rw-r--r--src/webengine/api/qquickwebenginescript.h114
-rw-r--r--src/webengine/api/qquickwebenginescript_p.h82
-rw-r--r--src/webengine/api/qquickwebenginescript_p_p.h87
-rw-r--r--src/webengine/api/qquickwebengineview.cpp11
-rw-r--r--src/webengine/api/qquickwebengineview_p.h2
-rw-r--r--src/webengine/doc/src/qtwebengine-overview.qdoc15
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.h1
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.h1
-rw-r--r--src/webengine/webengine.pro1
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp5
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h1
-rw-r--r--tests/auto/quick/publicapi/tst_publicapi.cpp2
-rw-r--r--tests/auto/quick/qmltests/data/tst_userScripts.qml19
-rw-r--r--tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp25
-rw-r--r--tests/auto/widgets/qwebenginepage/qwebenginepage.pro2
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp204
-rw-r--r--tests/auto/widgets/qwebengineview/qwebengineview.pro1
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp267
-rw-r--r--tools/qmake/mkspecs/features/configure.prf12
-rw-r--r--tools/qmake/mkspecs/features/functions.prf21
-rw-r--r--tools/qmake/mkspecs/features/gn_generator.prf36
54 files changed, 1517 insertions, 573 deletions
diff --git a/configure.json b/configure.json
index 03b9611c1..c91c2e6bf 100644
--- a/configure.json
+++ b/configure.json
@@ -9,11 +9,13 @@
"commandline": {
"options": {
"alsa": "boolean",
+ "embedded": "boolean",
"pepper-plugins": "boolean",
"printing-and-pdf": "boolean",
"proprietary-codecs": "boolean",
"pulseaudio": "boolean",
- "spellchecker": "boolean"
+ "spellchecker": "boolean",
+ "webrtc": "boolean"
}
},
@@ -41,10 +43,21 @@
"gn": {
"label": "system gn",
"type": "detectGn"
+ },
+ "embedded": {
+ "label": "embedded",
+ "type": "embedded"
}
},
"features": {
+ "embedded": {
+ "label": "Embedded build",
+ "condition": "config.unix",
+ "autoDetect": "tests.embedded",
+ "purpose": "Enables the embedded build configuration",
+ "output": [ "privateFeature" ]
+ },
"alsa": {
"label": "ALSA",
"condition": "config.unix && libs.alsa",
@@ -58,14 +71,14 @@
},
"pepper-plugins": {
"label": "Pepper Plugins",
- "autoDetect": "!features.cross_compile",
+ "autoDetect": "!features.embedded",
"purpose": "Enables use of Pepper Flash and Widevine plugins",
"output": [ "privateFeature" ]
},
"printing-and-pdf": {
"label": "Printing and PDF",
"condition": "module.printsupport && features.printer",
- "autoDetect": "!features.cross_compile",
+ "autoDetect": "!features.embedded",
"purpose": "Enables printing and output to PDF",
"output": [ "privateFeature" ]
},
@@ -80,6 +93,12 @@
"purpose": "Enables the use of Chromium's spellchecker",
"output": [ "privateFeature" ]
},
+ "webrtc": {
+ "label": "WebRTC",
+ "autoDetect": "!features.embedded",
+ "purpose": "Enables WebRTC support",
+ "output": [ "privateFeature" ]
+ },
"system-ninja": {
"label": "Using system ninja",
"condition": "tests.ninja",
@@ -87,6 +106,7 @@
},
"system-gn": {
"label": "Using system gn",
+ "autoDetect": false,
"condition": "tests.gn",
"output": [ "privateFeature" ]
}
@@ -96,11 +116,12 @@
{
"section": "Qt WebEngine",
"entries": [
+ "embedded",
"pepper-plugins",
"printing-and-pdf",
"proprietary-codecs",
"spellchecker",
- "system-gn",
+ "webrtc",
"system-ninja",
{
"type": "feature",
diff --git a/configure.pri b/configure.pri
index b6693aecf..23f31686e 100644
--- a/configure.pri
+++ b/configure.pri
@@ -23,3 +23,12 @@ defineTest(qtConfTest_detectGn) {
qtLog("Building own gn")
return(false)
}
+
+defineTest(qtConfTest_embedded) {
+ lessThan(QT_MINOR_VERSION, 9) {
+ cross_compile: return(true)
+ return(false)
+ }
+ $$qtConfEvaluate("features.cross_compile"): return(true)
+ return(false)
+}
diff --git a/examples/webenginewidgets/spellchecker/webview.cpp b/examples/webenginewidgets/spellchecker/webview.cpp
index 86e21ab13..0e52e7628 100644
--- a/examples/webenginewidgets/spellchecker/webview.cpp
+++ b/examples/webenginewidgets/spellchecker/webview.cpp
@@ -65,7 +65,7 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
}
QWebEngineProfile *profile = page()->profile();
- const QString &language = profile->spellCheckLanguages().first();
+ const QStringList &languages = profile->spellCheckLanguages();
QMenu *menu = page()->createStandardContextMenu();
menu->addSeparator();
@@ -83,7 +83,7 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
QAction *action = subMenu->addAction(str);
action->setCheckable(true);
QString lang = m_spellCheckLanguages[str];
- action->setChecked(language == lang);
+ action->setChecked(languages.contains(lang));
connect(action, &QAction::triggered, this, [profile, lang](){
profile->setSpellCheckLanguages(QStringList()<<lang);
});
diff --git a/src/core/config/common.pri b/src/core/config/common.pri
index f822ab7cc..7307c4a46 100644
--- a/src/core/config/common.pri
+++ b/src/core/config/common.pri
@@ -1,33 +1,79 @@
# Shared configuration for all our supported platforms
-# Trigger Qt-specific build conditions.
-GYP_CONFIG += use_qt=1
-# We do not want to ship more external binary blobs, so let v8 embed its startup data.
-GYP_CONFIG += v8_use_external_startup_data=0
-# WebSpeech requires Google API keys and adds dependencies on speex and flac.
-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
-
-use?(printing) {
- GYP_CONFIG += enable_basic_printing=1 enable_print_preview=1
-} else {
- GYP_CONFIG += enable_basic_printing=0 enable_print_preview=0
-}
+use?(gn) {
+ gn_args += \
+ use_qt=true \
+ is_component_build=false \
+ enable_remoting=false \
+ enable_nacl=false \
+ use_experimental_allocator_shim=false \
+ use_allocator=\"none\" \
+ v8_use_external_startup_data=false \
+ treat_warnings_as_errors=false
-use?(pdf) {
- GYP_CONFIG += enable_pdf=1
-} else {
- GYP_CONFIG += enable_pdf=0
-}
+ use?(printing) {
+ gn_args += enable_basic_printing=true enable_print_preview=true
+ } else {
+ gn_args += enable_basic_printing=false enable_print_preview=false
+ }
+
+ use?(pdf) {
+ gn_args += enable_pdf=true
+ } else {
+ gn_args += enable_pdf=false
+ }
+
+ use?(pepper_plugins) {
+ gn_args += enable_plugins=true enable_widevine=true
+ } else {
+ gn_args += enable_plugins=false enable_widevine=false
+ }
+
+ use?(spellchecker) {
+ gn_args += enable_spellcheck=true
+ } else {
+ gn_args += enable_spellcheck=false
+ }
+
+ use?(webrtc) {
+ gn_args += enable_webrtc=true
+ } else {
+ gn_args += enable_webrtc=false
+ }
-use?(pepper_plugins) {
- GYP_CONFIG += enable_plugins=1 enable_widevine=1
} else {
- GYP_CONFIG += enable_plugins=0 enable_widevine=0
+ # Trigger Qt-specific build conditions.
+ GYP_CONFIG += use_qt=1
+ # We do not want to ship more external binary blobs, so let v8 embed its startup data.
+ GYP_CONFIG += v8_use_external_startup_data=0
+ # WebSpeech requires Google API keys and adds dependencies on speex and flac.
+ 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
+
+ use?(printing) {
+ GYP_CONFIG += enable_basic_printing=1 enable_print_preview=1
+ } else {
+ GYP_CONFIG += enable_basic_printing=0 enable_print_preview=0
+ }
+
+ use?(pdf) {
+ GYP_CONFIG += enable_pdf=1
+ } else {
+ GYP_CONFIG += enable_pdf=0
+ }
+
+ use?(pepper_plugins) {
+ GYP_CONFIG += enable_plugins=1 enable_widevine=1
+ } else {
+ GYP_CONFIG += enable_plugins=0 enable_widevine=0
+ }
}
+
+use?(webrtc): GYP_CONFIG += enable_webrtc=1
+else: GYP_CONFIG += enable_webrtc=0
diff --git a/src/core/config/desktop_linux.pri b/src/core/config/desktop_linux.pri
index 92491fc1c..e8db4248f 100644
--- a/src/core/config/desktop_linux.pri
+++ b/src/core/config/desktop_linux.pri
@@ -1,17 +1,29 @@
-GYP_ARGS += "-D qt_os=\"desktop_linux\""
-
include(linux.pri)
-GYP_CONFIG += \
- desktop_linux=1
+use?(gn) {
+ gn_args += \
+ is_clang=false \
+ use_sysroot=false
+
+ use?(icecc) {
+ gn_args += use_debug_fission=false
+ }
-clang {
- 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
+
+ GYP_ARGS += "-D qt_os=\"desktop_linux\""
+
+ GYP_CONFIG += \
+ desktop_linux=1
+
+ clang {
+ 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/embedded_linux.pri b/src/core/config/embedded_linux.pri
index 08c8c1661..c9de47562 100644
--- a/src/core/config/embedded_linux.pri
+++ b/src/core/config/embedded_linux.pri
@@ -18,7 +18,6 @@ GYP_CONFIG += \
enable_session_service=0 \
enable_task_manager=0 \
enable_themes=0 \
- enable_webrtc=0 \
gtest_target_type=none \
host_clang=0 \
notifications=0 \
diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri
index b91e795ca..8509c0c8e 100644
--- a/src/core/config/linux.pri
+++ b/src/core/config/linux.pri
@@ -2,6 +2,44 @@ include(common.pri)
include($$QTWEBENGINE_OUT_ROOT/qtwebengine-config.pri)
QT_FOR_CONFIG += gui-private webengine-private
+use?(gn) {
+ gn_args += \
+ use_gconf=false \
+ use_gio=false \
+ use_kerberos=false \
+ linux_use_bundled_binutils=false
+
+ #qtConfig(system-zlib): use?(system_minizip): gn_args += use_system_zlib=true use_system_minizip=true
+ #qtConfig(system-png): gn_args += use_system_libpng=true
+ qtConfig(system-jpeg): gn_args += use_system_libjpeg=true
+ qtConfig(system-harfbuzz): use?(system_harfbuzz): gn_args += use_system_harfbuzz=true
+ !qtConfig(glib): gn_args += use_glib=false
+ qtConfig(pulseaudio) {
+ gn_args += use_pulseaudio=true
+ } else {
+ gn_args += use_pulseaudio=false
+ }
+ qtConfig(alsa) {
+ gn_args += use_alsa=true
+ } else {
+ gn_args += use_alsa=false
+ }
+
+ #use?(system_libevent): gn_args += use_system_libevent=true
+ #use?(system_libwebp): gn_args += use_system_libwebp=true
+ #use?(system_libsrtp): gn_args += use_system_libsrtp=true
+ #use?(system_libxslt): gn_args += use_system_libxml=true use_system_libxslt=true
+ #use?(system_jsoncpp): gn_args += use_system_jsoncpp=true
+ #use?(system_opus): gn_args += use_system_opus=true
+ #use?(system_snappy): gn_args += use_system_snappy=true
+ #use?(system_vpx): gn_args += use_system_libvpx=true
+ #use?(system_icu): gn_args += use_system_icu=true icu_use_data_file_flag=false
+ #use?(system_ffmpeg): gn_args += use_system_ffmpeg=true
+ #use?(system_protobuf): gn_args += use_system_protobuf=true
+
+ #gcc:!clang: greaterThan(QT_GCC_MAJOR_VERSION, 5): gn_args += no_delete_null_pointer_checks=true
+}
+
# linux_use_bundled_gold currently relies on a hardcoded relative path from chromium/src/out/(Release|Debug)
# Disable it along with the -Wl,--threads flag just in case gold isn't installed on the system.
GYP_CONFIG += \
diff --git a/src/core/config/mac_osx.pri b/src/core/config/mac_osx.pri
index dfc8d840b..e52051b0c 100644
--- a/src/core/config/mac_osx.pri
+++ b/src/core/config/mac_osx.pri
@@ -19,21 +19,42 @@ QMAKE_CLANG_PATH = $$eval(QMAKE_MAC_SDK.macx-clang.$${QMAKE_MAC_SDK}.QMAKE_CXX)
QMAKE_CLANG_PATH = "$${QMAKE_CLANG_DIR}/bin/clang++"
message("Using clang++ from $${QMAKE_CLANG_PATH}")
system("$${QMAKE_CLANG_PATH} --version")
-GYP_CONFIG += \
- qt_os=\"mac\" \
- mac_sdk_min=\"$${QMAKE_MAC_SDK_VERSION}\" \
- mac_deployment_target=\"$${QMAKE_MACOSX_DEPLOYMENT_TARGET}\" \
- make_clang_dir=\"$${QMAKE_CLANG_DIR}\" \
- clang_use_chrome_plugins=0
-
-# Force touch API is used in 49-based Chromium, which is included starting with 10.10.3 SDK, so we
-# disable the API usage if the SDK version is lower.
-!isMinOSXSDKVersion(10, 10, 3): GYP_CONFIG += disable_force_touch=1
-
-# Pass a supported -fstack-protect flag depending on Xcode version.
-lessThan(QMAKE_XCODE_VERSION, 6.3) {
- GYP_CONFIG += use_xcode_stack_protector_strong=0
-}
-QMAKE_MAC_SDK_PATH = "$$eval(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.path)"
-exists($$QMAKE_MAC_SDK_PATH): GYP_CONFIG += mac_sdk_path=\"$${QMAKE_MAC_SDK_PATH}\"
+
+use?(gn) {
+ gn_args += \
+ is_clang=true \
+ use_sysroot=false \
+ use_kerberos=false \
+ clang_base_path=\"$${QMAKE_CLANG_DIR}\" \
+ clang_use_chrome_plugins=false \
+ mac_deployment_target=\"$${QMAKE_MACOSX_DEPLOYMENT_TARGET}\" \
+ mac_sdk_min=\"$${QMAKE_MAC_SDK_VERSION}\"
+
+ use?(spellchecker) {
+ use?(native_spellchecker): gn_args += use_browser_spellchecker=true
+ else: gn_args += use_browser_spellchecker=false
+ } else {
+ macos: gn_args += use_browser_spellchecker=false
+ }
+
+} else {
+ GYP_CONFIG += \
+ qt_os=\"mac\" \
+ mac_sdk_min=\"$${QMAKE_MAC_SDK_VERSION}\" \
+ mac_deployment_target=\"$${QMAKE_MACOSX_DEPLOYMENT_TARGET}\" \
+ make_clang_dir=\"$${QMAKE_CLANG_DIR}\" \
+ clang_use_chrome_plugins=0
+
+ # Force touch API is used in 49-based Chromium, which is included starting with 10.10.3 SDK, so we
+ # disable the API usage if the SDK version is lower.
+ !isMinOSXSDKVersion(10, 10, 3): GYP_CONFIG += disable_force_touch=1
+
+ # Pass a supported -fstack-protect flag depending on Xcode version.
+ lessThan(QMAKE_XCODE_VERSION, 6.3) {
+ GYP_CONFIG += use_xcode_stack_protector_strong=0
+ }
+
+ QMAKE_MAC_SDK_PATH = "$$eval(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.path)"
+ exists($$QMAKE_MAC_SDK_PATH): GYP_CONFIG += mac_sdk_path=\"$${QMAKE_MAC_SDK_PATH}\"
+}
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 787586540..f9b6f31d8 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -386,7 +386,7 @@ void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost*
// SpellCheckMessageFilter is required for both Hunspell and Native configurations.
host->AddFilter(new SpellCheckMessageFilter(id));
#endif
-#if defined(Q_OS_MACOS) && defined(USE_BROWSER_SPELLCHECKER)
+#if defined(Q_OS_MACOS) && defined(ENABLE_SPELLCHECK) && defined(USE_BROWSER_SPELLCHECKER)
host->AddFilter(new SpellCheckMessageFilterPlatform(id));
#endif
#if defined(ENABLE_BASIC_PRINTING)
diff --git a/src/core/core.pro b/src/core/core.pro
index cda885921..a2f3c3753 100644
--- a/src/core/core.pro
+++ b/src/core/core.pro
@@ -14,15 +14,38 @@ core_module.depends = core_api
core_generator.file = core_generator.pro
core_generator.depends = core_headers
-
use?(gn) {
+ # core_gn_generator.pro is a dummy .pro file that is used by qmake
+ # to generate our main BUILD.gn file
+
+ core_icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat
+ core_icu.path = $$[QT_INSTALL_DATA]/resources
+ core_icu.CONFIG += no_check_exist
+
+ core_locales.files = $$OUT_PWD/$$getConfigDir()/qtwebengine_locales/*.pak
+ core_locales.path = $$[QT_INSTALL_TRANSLATIONS]/qtwebengine_locales
+ core_locales.CONFIG += no_check_exist
+
+ core_resources.files = \
+ $$OUT_PWD/$$getConfigDir()/qtwebengine_resources.pak \
+ $$OUT_PWD/$$getConfigDir()/qtwebengine_resources_100p.pak \
+ $$OUT_PWD/$$getConfigDir()/qtwebengine_resources_200p.pak \
+ $$OUT_PWD/$$getConfigDir()/qtwebengine_devtools_resources.pak
+ core_resources.path = $$[QT_INSTALL_DATA]/resources
+ core_resources.CONFIG += no_check_exist
+ INSTALLS += core_resources core_locales core_icu
gn_run.file = gn_run.pro
gn_run.depends = core_generator
- SUBDIRS += core_headers \
+ core_api.depends = gn_run
+
+ SUBDIRS += \
+ core_headers \
core_generator \
- gn_run
+ gn_run \
+ core_api \
+ core_module
} else {
# gyp_run.pro calls gyp through gyp_qtwebengine on the qmake step, and ninja on the make step.
diff --git a/src/core/core_generator.pro b/src/core/core_generator.pro
index e1e7ab1d9..ed47a47e9 100644
--- a/src/core/core_generator.pro
+++ b/src/core/core_generator.pro
@@ -12,7 +12,15 @@ include(core_common.pri)
macos {
# This fixes namespace builds on macOS. Specifically namespace ambiguity issues between Qt and
# Chromium forward declarations of NSString.
- forward_declaration_macro = $$shell_quote(\"Q_FORWARD_DECLARE_OBJC_CLASS(name)=class name;\")
+ contains(WEBENGINE_CONFIG, use_gn) {
+ # The single quotes are present so that qmake iteration does not interpret the space as
+ # delimiting a new value, they are removed before writing to the GN file, and the final shell
+ # quoting is done by GN itself.
+ forward_declaration_macro = "'Q_FORWARD_DECLARE_OBJC_CLASS(name)=class name;'"
+ } else {
+ # For GYP, quoting should be done by qmake itself.
+ forward_declaration_macro = $$shell_quote(\"Q_FORWARD_DECLARE_OBJC_CLASS(name)=class name;\")
+ }
} else {
forward_declaration_macro = "Q_FORWARD_DECLARE_OBJC_CLASS=QT_FORWARD_DECLARE_CLASS"
}
diff --git a/src/core/core_gn_config.pri b/src/core/core_gn_config.pri
index ea45977f5..fb671ddb2 100644
--- a/src/core/core_gn_config.pri
+++ b/src/core/core_gn_config.pri
@@ -1,6 +1,10 @@
CONFIG = gn_generator $$CONFIG
GN_SRC_DIR = $$PWD
-GN_FILE = $$OUT_PWD/BUILD.gn
+GN_FILE = $$OUT_PWD/$$getConfigDir()/BUILD.gn
GN_FIND_MOCABLES_SCRIPT = $$shell_path($$QTWEBENGINE_ROOT/tools/scripts/gn_find_mocables.py)
GN_RUN_BINARY_SCRIPT = $$shell_path($$QTWEBENGINE_ROOT/tools/scripts/gn_run_binary.py)
+GN_IMPORTS = $$PWD/qtwebengine.gni
+GN_INCLUDES = $$PWD/qtwebengine_sources.gni $$PWD/qtwebengine_resources.gni
+GN_CREATE_PRI = true
+QMAKE_INTERNAL_INCLUDED_FILES = $$GN_IMPORTS $$GN_INCLUDES $$GN_FILE
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index 596993457..a7853e524 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -4,9 +4,11 @@ include(core_common.pri)
# Needed to set a CFBundleIdentifier
QMAKE_INFO_PLIST = Info_mac.plist
-# Look for linking information produced by gyp for our target according to core_generated.gyp
-!include($$OUT_PWD/$$getConfigDir()/$${TARGET}_linking.pri) {
- error("Could not find the linking information that gyp should have generated.")
+use?(gn): linking_pri = $$OUT_PWD/$$getConfigDir()/$${TARGET}.pri
+else: linking_pri = $$OUT_PWD/$$getConfigDir()/$${TARGET}_linking.pri
+
+!include($$linking_pri) {
+ error("Could not find the linking information that gyp/gn should have generated.")
}
load(qt_module)
@@ -17,6 +19,30 @@ api_library_path = $$OUT_PWD/api/$$getConfigDir()
# Do not precompile any headers. We are only interested in the linker step.
PRECOMPILED_HEADER =
+use?(gn){
+ isEmpty(NINJA_OBJECTS): error("Missing object files from QtWebEngineCore linking pri.")
+ isEmpty(NINJA_LFLAGS): error("Missing linker flags from QtWebEngineCore linking pri")
+ isEmpty(NINJA_ARCHIVES): error("Missing archive files from QtWebEngineCore linking pri")
+ isEmpty(NINJA_LIBS): error("Missing library files from QtWebEngineCore linking pri")
+ NINJA_OBJECTS = $$eval($$list($$NINJA_OBJECTS))
+ # Do manual response file linking for macOS and Linux
+ unix {
+ RSP_FILE = $$OUT_PWD/$$getConfigDir()/$${TARGET}.rsp
+ for(object, NINJA_OBJECTS): RSP_CONTENT += $$object
+ write_file($$RSP_FILE, RSP_CONTENT)
+ macos:LIBS_PRIVATE += -Wl,-filelist,$$shell_quote($$RSP_FILE)
+ linux:LIBS_PRIVATE += @$$RSP_FILE
+ } else {
+ OBJECTS = $$NINJA_OBJECTS
+ }
+ linux: LIBS_PRIVATE += -Wl,--start-group $$NINJA_ARCHIVES -Wl,--end-group
+ else: LIBS_PRIVATE += $$NINJA_ARCHIVES
+ LIBS_PRIVATE += $$NINJA_LIB_DIRS $$NINJA_LIBS
+ QMAKE_LFLAGS += $$NINJA_LFLAGS
+ POST_TARGETDEPS += $$NINJA_TARGETDEPS
+}
+
+
LIBS_PRIVATE += -L$$api_library_path
CONFIG *= no_smart_library_merge
osx {
@@ -44,7 +70,12 @@ qtConfig(egl): CONFIG += egl
linux:qtConfig(separate_debug_info): QMAKE_POST_LINK="cd $(DESTDIR) && $(STRIP) --strip-unneeded $(TARGET)"
-REPACK_DIR = $$OUT_PWD/$$getConfigDir()/gen/repack
+use?(gn) {
+ REPACK_DIR = $$OUT_PWD/$$getConfigDir()
+} else {
+ REPACK_DIR = $$OUT_PWD/$$getConfigDir()/gen/repack
+}
+
# Duplicated from resources/resources.gyp
LOCALE_LIST = am ar bg bn ca cs da de el en-GB en-US es-419 es et fa fi fil fr gu he hi hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk sl sr sv sw ta te th tr uk vi zh-CN zh-TW
for(LOC, LOCALE_LIST) {
diff --git a/src/core/gn_run.pro b/src/core/gn_run.pro
index c379f9510..534f0c7b3 100644
--- a/src/core/gn_run.pro
+++ b/src/core/gn_run.pro
@@ -7,8 +7,15 @@ TEMPLATE = aux
build_pass|!debug_and_release {
+ macos: include(config/mac_osx.pri)
+ linux: include(config/desktop_linux.pri)
+ isEmpty(gn_args): error(No gn_args found please make sure you have valid configuration.)
+
ninja_binary = ninja
+ gn_binary = gn
+
runninja.target = run_ninja
+ rungn.target = run_gn
!qtConfig(system-ninja) {
ninja_binary = $$shell_quote($$shell_path($$ninjaPath()))
@@ -18,18 +25,35 @@ build_pass|!debug_and_release {
runninja.depends = buildninja
}
+ CONFIG(release, debug|release):
+ gn_args += is_debug=false
+
+ gn_args += "qtwebengine_target=\"$$shell_path($$OUT_PWD/$$getConfigDir()):QtWebEngineCore\""
+
!qtConfig(system-gn) {
+ gn_binary = $$shell_quote($$shell_path($$gnPath()))
buildgn.target = build_gn
- buildgn.commands = $$buildGn()
- !qtConfig(system-ninja): buildgn.depends = buildninja
+ buildgn.commands = $$buildGn($$gn_args)
+ !qtConfig(system-ninja) {
+ buildgn.depends = buildninja
+ rungn.depends = buildninja
+ }
QMAKE_EXTRA_TARGETS += buildgn
- runninja.depends = buildgn
}
- runninja.commands = $$ninja_binary \$\(NINJAFLAGS\) -C $$shell_quote($$OUT_PWD/$$getConfigDir())
+ gn_args = $$shell_quote($$gn_args)
+ gn_src_root = $$shell_quote($$shell_path($$QTWEBENGINE_ROOT/$$getChromiumSrcDir()))
+ gn_build_root = $$shell_quote($$shell_path($$OUT_PWD/$$getConfigDir()))
+ rungn.commands = $$gn_binary gen $$gn_build_root --args=$$gn_args --root=$$gn_src_root
+ QMAKE_EXTRA_TARGETS += rungn
+
+ runninja.commands = $$ninja_binary \$\(NINJAFLAGS\) -v -C $$shell_quote($$OUT_PWD/$$getConfigDir()) QtWebEngineCore
+ runninja.depends += rungn
QMAKE_EXTRA_TARGETS += runninja
- default_target.depends = buildgn
+ build_pass:build_all: default_target.target = all
+ else: default_target.target = first
+ default_target.depends = runninja
QMAKE_EXTRA_TARGETS += default_target
} else {
diff --git a/src/core/gyp_run.pro b/src/core/gyp_run.pro
index c583845e9..fa8f73de4 100644
--- a/src/core/gyp_run.pro
+++ b/src/core/gyp_run.pro
@@ -9,7 +9,7 @@ isQtMinimum(5, 8) {
TEMPLATE = aux
-cross_compile {
+contains(WEBENGINE_CONFIG, embedded_build) {
GYP_ARGS = "-D qt_cross_compile=1"
posix: GYP_ARGS += "-D os_posix=1"
qnx: include(config/embedded_qnx.pri)
diff --git a/src/core/qtwebengine.gni b/src/core/qtwebengine.gni
new file mode 100644
index 000000000..4e561e7a9
--- /dev/null
+++ b/src/core/qtwebengine.gni
@@ -0,0 +1,47 @@
+chromium_version = exec_script("//build/util/version.py", [ "-f", rebase_path("//chrome/VERSION"),
+ "-t", "@MAJOR@.@MINOR@.@BUILD@.@PATCH@"],
+ "list lines")
+
+declare_args() {
+ use_qt = true
+}
+
+include_dirs = [
+ "//skia/config",
+ "//third_party/skia/include/core"
+]
+
+deps = [
+ "//base",
+ "//components/cdm/renderer",
+ "//components/devtools_http_handler",
+ "//components/error_page/common",
+ "//components/keyed_service/content",
+ "//components/visitedlink/browser",
+ "//components/visitedlink/renderer",
+ "//components/web_cache/browser",
+ "//components/web_cache/public/interfaces",
+ "//components/web_cache/renderer",
+ "//content/public/app:browser",
+ "//content/public/browser",
+ "//content/public/common",
+ "//net:net_browser_services",
+ "//services/shell/public/cpp",
+ "//skia",
+ "//third_party/WebKit/public:blink",
+ "//third_party/widevine/cdm:version_h",
+ "//ui/accessibility",
+ "//third_party/mesa:mesa_headers",
+ ":qtwebengine_sources",
+ ":qtwebengine_resources"
+]
+
+if (enable_widevine) {
+ deps += [ "//components/cdm/renderer"]
+}
+
+# fixme:
+defines = [
+ "QTWEBENGINEPROCESS_NAME=\"QtWebEngineProcess\"",
+ "CHROMIUM_VERSION=\"" + chromium_version[0] + "\""
+]
diff --git a/src/core/qtwebengine.gypi b/src/core/qtwebengine.gypi
index 5131ce8cc..b83b1cbfa 100644
--- a/src/core/qtwebengine.gypi
+++ b/src/core/qtwebengine.gypi
@@ -5,6 +5,11 @@
'variables': {
'version_script_location%': '<(chromium_src_dir)/build/util/version.py',
},
+ 'configurations': {
+ 'Release': {
+ 'defines': [ 'QT_NO_DEBUG' ],
+ },
+ },
'dependencies': [
'<(chromium_src_dir)/base/base.gyp:base',
'<(chromium_src_dir)/base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
diff --git a/src/core/qtwebengine_resources.gni b/src/core/qtwebengine_resources.gni
new file mode 100644
index 000000000..e3cd42169
--- /dev/null
+++ b/src/core/qtwebengine_resources.gni
@@ -0,0 +1,86 @@
+import("//tools/grit/repack.gni")
+import("//build/config/locales.gni")
+import("//chrome/chrome_repack_locales.gni")
+
+group("qtwebengine_resources") {
+ deps = [
+ "//chrome/app:generated_resources",
+ "//components/resources:components_resources",
+ ":qtwebengine_repack_resources",
+ ":qtwebengine_repack_resources_100",
+ ":qtwebengine_repack_resources_200",
+ ":qtwebengine_repack_resources_devtools",
+ ":qtwebengine_repack_locales_pack"
+ ]
+}
+
+repack("qtwebengine_repack_resources") {
+ sources = [
+ "$root_gen_dir/blink/public/resources/blink_resources.pak",
+ "$root_gen_dir/components/components_resources.pak",
+ "$root_gen_dir/content/content_resources.pak",
+ "$root_gen_dir/net/net_resources.pak",
+ "$root_gen_dir/ui/resources/webui_resources.pak",
+ ]
+ output = "$root_out_dir/qtwebengine_resources.pak"
+ deps = [
+ "//components/resources:components_resources_grit",
+ "//content:resources_grit",
+ "//net:net_resources_grit",
+ "//third_party/WebKit/public:resources_grit",
+ "//ui/resources:webui_resources_grd_grit",
+ ]
+}
+
+repack("qtwebengine_repack_resources_100") {
+ sources = [
+ "$root_gen_dir/ui/resources/ui_resources_100_percent.pak",
+ "$root_gen_dir/components/components_resources_100_percent.pak",
+ "$root_gen_dir/content/app/resources/content_resources_100_percent.pak",
+ "$root_gen_dir/chrome/renderer_resources_100_percent.pak",
+ "$root_gen_dir/blink/public/resources/blink_image_resources_100_percent.pak",
+ ]
+ output = "$root_out_dir/qtwebengine_resources_100p.pak"
+ deps = [
+ "//third_party/WebKit/public:image_resources_grit",
+ "//chrome/renderer:resources_grit",
+ "//components/resources:components_scaled_resources_grit",
+ "//content/app/resources:resources_grit",
+ "//ui/resources:ui_resources_grd_grit"
+ ]
+}
+
+repack("qtwebengine_repack_resources_200") {
+ sources = [
+ "$root_gen_dir/ui/resources/ui_resources_200_percent.pak",
+ "$root_gen_dir/components/components_resources_200_percent.pak",
+ "$root_gen_dir/content/app/resources/content_resources_200_percent.pak",
+ "$root_gen_dir/chrome/renderer_resources_200_percent.pak",
+ "$root_gen_dir/blink/public/resources/blink_image_resources_200_percent.pak",
+ ]
+ output = "$root_out_dir/qtwebengine_resources_200p.pak"
+ deps = [
+ "//third_party/WebKit/public:image_resources_grit",
+ "//chrome/renderer:resources_grit",
+ "//components/resources:components_scaled_resources_grit",
+ "//content/app/resources:resources_grit",
+ "//ui/resources:ui_resources_grd_grit"
+ ]
+}
+
+repack("qtwebengine_repack_resources_devtools") {
+ sources = [
+ "$root_gen_dir/blink/devtools_resources.pak",
+ ]
+ output = "$root_out_dir/qtwebengine_devtools_resources.pak"
+ deps = [
+ "//content/browser/devtools:devtools_resources_grit"
+ ]
+}
+
+chrome_repack_locales("qtwebengine_repack_locales_pack") {
+ input_locales = locales
+ output_dir_name = "qtwebengine_locales"
+ output_locales = locales
+}
+
diff --git a/src/core/qtwebengine_sources.gni b/src/core/qtwebengine_sources.gni
new file mode 100644
index 000000000..2d3503e98
--- /dev/null
+++ b/src/core/qtwebengine_sources.gni
@@ -0,0 +1,128 @@
+source_set("qtwebengine_sources") {
+ include_dirs = [
+ "//skia/config",
+ "//third_party/skia/include/core"
+ ]
+ deps = []
+ sources = [
+ "//chrome/browser/media/desktop_media_list.h",
+ "//chrome/browser/media/desktop_streams_registry.cc",
+ "//chrome/browser/media/desktop_streams_registry.h",
+ "//chrome/common/chrome_switches.cc",
+ "//chrome/common/chrome_switches.h",
+ "//components/prefs/testing_pref_store.cc",
+ "//components/prefs/testing_pref_store.h",
+ "//extensions/common/constants.cc",
+ "//extensions/common/constants.h",
+ "//extensions/common/url_pattern.cc",
+ "//extensions/common/url_pattern.h",
+ ]
+
+ if (enable_plugins) {
+ sources += [
+ "//chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc",
+ "//chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h",
+ "//chrome/renderer/pepper/pepper_flash_font_file_host.cc",
+ "//chrome/renderer/pepper/pepper_flash_font_file_host.h",
+ "//chrome/renderer/pepper/pepper_shared_memory_message_filter.cc",
+ "//chrome/renderer/pepper/pepper_shared_memory_message_filter.h",
+ ]
+
+ deps += [
+ # Need to depend on //content/ppapi_plugin, which is private, thus depending on parent.
+ "//content",
+ ]
+ }
+
+ if (enable_spellcheck) {
+ sources += [
+ "//chrome/browser/spellchecker/feedback.cc",
+ "//chrome/browser/spellchecker/feedback.h",
+ "//chrome/browser/spellchecker/feedback_sender.cc",
+ "//chrome/browser/spellchecker/feedback_sender.h",
+ "//chrome/browser/spellchecker/misspelling.cc",
+ "//chrome/browser/spellchecker/misspelling.h",
+ "//chrome/browser/spellchecker/spellcheck_action.cc",
+ "//chrome/browser/spellchecker/spellcheck_action.h",
+ "//chrome/browser/spellchecker/spellcheck_custom_dictionary.cc",
+ "//chrome/browser/spellchecker/spellcheck_custom_dictionary.h",
+ "//chrome/browser/spellchecker/spellcheck_factory.cc",
+ "//chrome/browser/spellchecker/spellcheck_factory.h",
+ "//chrome/browser/spellchecker/spellcheck_host_metrics.cc",
+ "//chrome/browser/spellchecker/spellcheck_host_metrics.h",
+ "//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc",
+ "//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h",
+ "//chrome/browser/spellchecker/spellcheck_message_filter.cc",
+ "//chrome/browser/spellchecker/spellcheck_message_filter.h",
+ "//chrome/browser/spellchecker/spellcheck_platform_mac.mm",
+ "//chrome/browser/spellchecker/spellcheck_service.cc",
+ "//chrome/browser/spellchecker/spellcheck_service.h",
+ "//chrome/browser/spellchecker/spelling_service_client.cc",
+ "//chrome/browser/spellchecker/spelling_service_client.h",
+ "//chrome/browser/spellchecker/word_trimmer.cc",
+ "//chrome/browser/spellchecker/word_trimmer.h",
+ "//chrome/common/common_message_generator.cc",
+ "//chrome/common/pref_names.cc",
+ "//chrome/common/pref_names.h",
+ "//chrome/common/spellcheck_bdict_language.h",
+ "//chrome/common/spellcheck_common.cc",
+ "//chrome/common/spellcheck_common.h",
+ "//chrome/common/spellcheck_marker.h",
+ "//chrome/common/spellcheck_messages.h",
+ "//chrome/common/spellcheck_result.h",
+ "//chrome/renderer/spellchecker/custom_dictionary_engine.cc",
+ "//chrome/renderer/spellchecker/custom_dictionary_engine.h",
+ "//chrome/renderer/spellchecker/hunspell_engine.cc",
+ "//chrome/renderer/spellchecker/hunspell_engine.h",
+ "//chrome/renderer/spellchecker/spellcheck.cc",
+ "//chrome/renderer/spellchecker/spellcheck.h",
+ "//chrome/renderer/spellchecker/spellcheck_language.cc",
+ "//chrome/renderer/spellchecker/spellcheck_language.h",
+ "//chrome/renderer/spellchecker/spellcheck_provider.cc",
+ "//chrome/renderer/spellchecker/spellcheck_provider.h",
+ "//chrome/renderer/spellchecker/spellcheck_worditerator.cc",
+ "//chrome/renderer/spellchecker/spellcheck_worditerator.h",
+ "//chrome/renderer/spellchecker/spelling_engine.h",
+ ]
+ include_dirs += [
+ "//third_party/WebKit"
+ ]
+ deps += [
+ "//third_party/icu",
+ "//third_party/hunspell",
+ "//chrome/tools/convert_dict"
+ ]
+
+ if (is_mac && use_browser_spellchecker) {
+ sources += [
+ "//chrome/browser/spellchecker/spellcheck_message_filter_platform.h",
+ "//chrome/browser/spellchecker/spellcheck_message_filter_platform_mac.cc",
+ ]
+ }
+ }
+
+ if (enable_basic_printing || enable_print_preview) {
+ sources += [
+ "//chrome/browser/printing/printer_query.cc",
+ "//chrome/browser/printing/printer_query.h",
+ "//chrome/browser/printing/print_job.cc",
+ "//chrome/browser/printing/print_job.h",
+ "//chrome/browser/printing/print_job_manager.cc",
+ "//chrome/browser/printing/print_job_manager.h",
+ "//chrome/browser/printing/print_job_worker.cc",
+ "//chrome/browser/printing/print_job_worker.h",
+ "//chrome/browser/printing/print_job_worker_owner.cc",
+ "//chrome/browser/printing/print_job_worker_owner.h",
+ ]
+ }
+
+ if (enable_pdf) {
+ deps += [
+ "//pdf",
+ "//components/printing/browser",
+ "//components/printing/renderer",
+ ]
+ }
+
+}
+
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index fef3831e3..280a0475d 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -116,7 +116,7 @@ static inline Qt::InputMethodHints toQtInputMethodHints(ui::TextInputType inputT
case ui::TEXT_INPUT_TYPE_SEARCH:
return Qt::ImhPreferLowercase | Qt::ImhNoAutoUppercase;
case ui::TEXT_INPUT_TYPE_PASSWORD:
- return Qt::ImhSensitiveData | Qt::ImhNoPredictiveText | Qt::ImhNoAutoUppercase;
+ return Qt::ImhSensitiveData | Qt::ImhNoPredictiveText | Qt::ImhNoAutoUppercase | Qt::ImhHiddenText;
case ui::TEXT_INPUT_TYPE_EMAIL:
return Qt::ImhEmailCharactersOnly;
case ui::TEXT_INPUT_TYPE_NUMBER:
@@ -575,6 +575,9 @@ void RenderWidgetHostViewQt::TextInputStateChanged(const content::TextInputState
{
m_currentInputType = params.type;
m_delegate->inputMethodStateChanged(params.type != ui::TEXT_INPUT_TYPE_NONE);
+ m_delegate->setInputMethodHints(toQtInputMethodHints(params.type));
+
+ m_surroundingText = QString::fromStdString(params.value);
}
void RenderWidgetHostViewQt::ImeCancelComposition()
@@ -838,7 +841,7 @@ QVariant RenderWidgetHostViewQt::inputMethodQuery(Qt::InputMethodQuery query) co
case Qt::ImAnchorPosition:
return static_cast<uint>(m_anchorPositionWithinSelection);
case Qt::ImSurroundingText:
- return toQt(selection_text_);
+ return m_surroundingText;
case Qt::ImCurrentSelection:
return toQt(GetSelectedText());
case Qt::ImMaximumTextLength:
@@ -971,7 +974,13 @@ void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev)
} else {
if (ev->type() == QEvent::KeyRelease) {
m_receivedEmptyImeText = false;
- m_host->ImeConfirmComposition(toString16(ev->text()), gfx::Range::InvalidRange(),
+ m_host->ImeSetComposition(toString16(ev->text()),
+ std::vector<blink::WebCompositionUnderline>(),
+ gfx::Range::InvalidRange(),
+ gfx::Range::InvalidRange().start(),
+ gfx::Range::InvalidRange().end());
+ m_host->ImeConfirmComposition(base::string16(),
+ gfx::Range::InvalidRange(),
false);
m_imeInProgress = false;
}
@@ -980,17 +989,16 @@ void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev)
}
content::NativeWebKeyboardEvent webEvent = WebEventFactory::toWebKeyboardEvent(ev);
- if (webEvent.type == blink::WebInputEvent::RawKeyDown && !ev->text().isEmpty()) {
+ bool keyDownTextInsertion = webEvent.type == blink::WebInputEvent::RawKeyDown && webEvent.text[0];
+ webEvent.skip_in_browser = keyDownTextInsertion;
+ m_host->ForwardKeyboardEvent(webEvent);
+
+ if (keyDownTextInsertion) {
// Blink won't consume the RawKeyDown, but rather the Char event in this case.
// Make sure to skip the former on the way back. The same os_event will be set on both of them.
webEvent.skip_in_browser = true;
- m_host->ForwardKeyboardEvent(webEvent);
-
- webEvent.skip_in_browser = false;
webEvent.type = blink::WebInputEvent::Char;
m_host->ForwardKeyboardEvent(webEvent);
- } else {
- m_host->ForwardKeyboardEvent(webEvent);
}
}
@@ -1002,9 +1010,6 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev)
QString commitString = ev->commitString();
QString preeditString = ev->preeditString();
- int replacementStart = ev->replacementStart();
- int replacementLength = ev->replacementLength();
-
int cursorPositionInPreeditString = -1;
gfx::Range selectionRange = gfx::Range::InvalidRange();
@@ -1067,33 +1072,45 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev)
}
}
- gfx::Range replacementRange = (replacementLength > 0) ? gfx::Range(replacementStart, replacementStart + replacementLength)
- : gfx::Range::InvalidRange();
+ int replacementLength = ev->replacementLength();
+ gfx::Range replacementRange = gfx::Range::InvalidRange();
- auto setCompositionForPreEditString = [&](){
+ if (replacementLength > 0)
+ {
+ int start = ev->replacementStart();
+
+ if (start >= 0)
+ replacementRange = gfx::Range(start, start + replacementLength);
+ else if (m_surroundingText.length() + start >= 0) {
+ start = m_surroundingText.length() + start;
+ replacementRange = gfx::Range(start, start + replacementLength);
+ }
+ }
+
+ auto setCompositionString = [&](const QString &compositionString){
ensureValidSelectionRange();
- m_host->ImeSetComposition(toString16(preeditString),
+ m_host->ImeSetComposition(toString16(compositionString),
underlines,
replacementRange,
selectionRange.start(),
selectionRange.end());
};
- if (!commitString.isEmpty()) {
- m_host->ImeConfirmComposition(toString16(commitString), replacementRange, false);
+ if (!commitString.isEmpty() || replacementLength > 0) {
+ setCompositionString(commitString);
+ m_host->ImeConfirmComposition(base::string16(), gfx::Range::InvalidRange(), false);
// We might get a commit string and a pre-edit string in a single event, which means
// we need to confirm the last composition, and start a new composition.
if (!preeditString.isEmpty()) {
- setCompositionForPreEditString();
+ setCompositionString(preeditString);
m_imeInProgress = true;
} else {
m_imeInProgress = false;
}
- m_receivedEmptyImeText = false;
-
+ m_receivedEmptyImeText = commitString.isEmpty();
} else if (!preeditString.isEmpty()) {
- setCompositionForPreEditString();
+ setCompositionString(preeditString);
m_imeInProgress = true;
m_receivedEmptyImeText = false;
} else {
@@ -1115,7 +1132,10 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev)
QGuiApplication::postEvent(qApp->focusObject(), eventCopy);
} else {
m_receivedEmptyImeText = false;
- m_host->ImeCancelComposition();
+ if (m_imeInProgress) {
+ m_imeInProgress = false;
+ m_host->ImeCancelComposition();
+ }
}
}
}
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index 0b2d7bc9d..2f5d97b67 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -244,6 +244,8 @@ private:
gfx::Vector2dF m_lastScrollOffset;
gfx::SizeF m_lastContentsSize;
+
+ QString m_surroundingText;
};
} // namespace QtWebEngineCore
diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h
index 1e50c8f08..1e1234e72 100644
--- a/src/core/render_widget_host_view_qt_delegate.h
+++ b/src/core/render_widget_host_view_qt_delegate.h
@@ -112,6 +112,7 @@ public:
virtual void resize(int width, int height) = 0;
virtual void move(const QPoint &) = 0;
virtual void inputMethodStateChanged(bool editorVisible) = 0;
+ virtual void setInputMethodHints(Qt::InputMethodHints hints) = 0;
virtual void setClearColor(const QColor &color) = 0;
};
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 9de2085ba..2534286bf 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -348,7 +348,7 @@ WebContentsAdapterPrivate::WebContentsAdapterPrivate()
, adapterClient(0)
, nextRequestId(CallbackDirectory::ReservedCallbackIdsEnd)
, lastFindRequestId(0)
- , currentDropAction(Qt::IgnoreAction)
+ , currentDropAction(blink::WebDragOperationNone)
, inDragUpdateLoop(false)
, updateDragCursorMessagePollingTimer(new QTimer)
{
@@ -1153,6 +1153,18 @@ static QMimeData *mimeDataFromDropData(const content::DropData &dropData)
return mimeData;
}
+static blink::WebDragOperationsMask toWeb(const Qt::DropActions action)
+{
+ int result = blink::WebDragOperationNone;
+ if (action & Qt::CopyAction)
+ result |= blink::WebDragOperationCopy;
+ if (action & Qt::LinkAction)
+ result |= blink::WebDragOperationLink;
+ if (action & Qt::MoveAction)
+ result |= blink::WebDragOperationMove;
+ return static_cast<blink::WebDragOperationsMask>(result);
+}
+
void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropData &dropData,
Qt::DropActions allowedActions, const QPixmap &pixmap,
const QPoint &offset)
@@ -1169,7 +1181,7 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD
d->currentDropData->file_contents.clear();
d->currentDropData->file_description_filename.clear();
- d->currentDropAction = Qt::IgnoreAction;
+ d->currentDropAction = blink::WebDragOperationNone;
QDrag *drag = new QDrag(dragSource); // will be deleted by Qt's DnD implementation
bool dValid = true;
QMetaObject::Connection onDestroyed = QObject::connect(dragSource, &QObject::destroyed, [&dValid](){
@@ -1192,25 +1204,17 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD
if (dValid) {
if (d->webContents) {
content::RenderViewHost *rvh = d->webContents->GetRenderViewHost();
- if (rvh)
+ if (rvh) {
+ rvh->DragSourceEndedAt(d->lastDragClientPos.x(), d->lastDragClientPos.y(),
+ d->lastDragScreenPos.x(), d->lastDragScreenPos.y(),
+ d->currentDropAction);
rvh->DragSourceSystemDragEnded();
+ }
}
d->currentDropData.reset();
}
}
-static blink::WebDragOperationsMask toWeb(const Qt::DropActions action)
-{
- int result = blink::WebDragOperationNone;
- if (action & Qt::CopyAction)
- result |= blink::WebDragOperationCopy;
- if (action & Qt::LinkAction)
- result |= blink::WebDragOperationLink;
- if (action & Qt::MoveAction)
- result |= blink::WebDragOperationMove;
- return static_cast<blink::WebDragOperationsMask>(result);
-}
-
static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeData *mimeData)
{
Q_ASSERT(dropData->filenames.empty());
@@ -1246,12 +1250,51 @@ void WebContentsAdapter::enterDrag(QDragEnterEvent *e, const QPoint &screenPos)
flagsFromModifiers(e->keyboardModifiers()));
}
+Qt::DropAction toQt(blink::WebDragOperation op)
+{
+ if (op & blink::WebDragOperationCopy)
+ return Qt::CopyAction;
+ if (op & blink::WebDragOperationLink)
+ return Qt::LinkAction;
+ if (op & blink::WebDragOperationMove || op & blink::WebDragOperationDelete)
+ return Qt::MoveAction;
+ return Qt::IgnoreAction;
+}
+
+static int toWeb(Qt::MouseButtons buttons)
+{
+ int result = 0;
+ if (buttons & Qt::LeftButton)
+ result |= blink::WebInputEvent::LeftButtonDown;
+ if (buttons & Qt::RightButton)
+ result |= blink::WebInputEvent::RightButtonDown;
+ if (buttons & Qt::MiddleButton)
+ result |= blink::WebInputEvent::MiddleButtonDown;
+ return result;
+}
+
+static int toWeb(Qt::KeyboardModifiers modifiers)
+{
+ int result = 0;
+ if (modifiers & Qt::ShiftModifier)
+ result |= blink::WebInputEvent::ShiftKey;
+ if (modifiers & Qt::ControlModifier)
+ result |= blink::WebInputEvent::ControlKey;
+ if (modifiers & Qt::AltModifier)
+ result |= blink::WebInputEvent::AltKey;
+ if (modifiers & Qt::MetaModifier)
+ result |= blink::WebInputEvent::MetaKey;
+ return result;
+}
+
Qt::DropAction WebContentsAdapter::updateDragPosition(QDragMoveEvent *e, const QPoint &screenPos)
{
Q_D(WebContentsAdapter);
content::RenderViewHost *rvh = d->webContents->GetRenderViewHost();
- rvh->DragTargetDragOver(toGfx(e->pos()), toGfx(screenPos), toWeb(e->possibleActions()),
- blink::WebInputEvent::LeftButtonDown);
+ d->lastDragClientPos = toGfx(e->pos());
+ d->lastDragScreenPos = toGfx(screenPos);
+ rvh->DragTargetDragOver(d->lastDragClientPos, d->lastDragScreenPos, toWeb(e->possibleActions()),
+ toWeb(e->mouseButtons()) | toWeb(e->keyboardModifiers()));
base::MessageLoop *currentMessageLoop = base::MessageLoop::current();
DCHECK(currentMessageLoop);
@@ -1273,13 +1316,13 @@ Qt::DropAction WebContentsAdapter::updateDragPosition(QDragMoveEvent *e, const Q
loop.Run();
d->updateDragCursorMessagePollingTimer->stop();
- return d->currentDropAction;
+ return toQt(d->currentDropAction);
}
-void WebContentsAdapter::updateDragAction(Qt::DropAction action)
+void WebContentsAdapter::updateDragAction(int action)
{
Q_D(WebContentsAdapter);
- d->currentDropAction = action;
+ d->currentDropAction = static_cast<blink::WebDragOperation>(action);
finishDragUpdate();
}
@@ -1298,7 +1341,9 @@ void WebContentsAdapter::endDragging(const QPoint &clientPos, const QPoint &scre
finishDragUpdate();
content::RenderViewHost *rvh = d->webContents->GetRenderViewHost();
rvh->FilterDropData(d->currentDropData.get());
- rvh->DragTargetDrop(*d->currentDropData, toGfx(clientPos), toGfx(screenPos), 0);
+ d->lastDragClientPos = toGfx(clientPos);
+ d->lastDragScreenPos = toGfx(screenPos);
+ rvh->DragTargetDrop(*d->currentDropData, d->lastDragClientPos, d->lastDragScreenPos, 0);
d->currentDropData.reset();
}
@@ -1398,4 +1443,15 @@ bool WebContentsAdapter::canViewSource()
return d->webContents->GetController().CanViewSource();
}
+ASSERT_ENUMS_MATCH(WebContentsAdapterClient::UnknownDisposition, WindowOpenDisposition::UNKNOWN)
+ASSERT_ENUMS_MATCH(WebContentsAdapterClient::CurrentTabDisposition, WindowOpenDisposition::CURRENT_TAB)
+ASSERT_ENUMS_MATCH(WebContentsAdapterClient::SingletonTabDisposition, WindowOpenDisposition::SINGLETON_TAB)
+ASSERT_ENUMS_MATCH(WebContentsAdapterClient::NewForegroundTabDisposition, WindowOpenDisposition::NEW_FOREGROUND_TAB)
+ASSERT_ENUMS_MATCH(WebContentsAdapterClient::NewBackgroundTabDisposition, WindowOpenDisposition::NEW_BACKGROUND_TAB)
+ASSERT_ENUMS_MATCH(WebContentsAdapterClient::NewPopupDisposition, WindowOpenDisposition::NEW_POPUP)
+ASSERT_ENUMS_MATCH(WebContentsAdapterClient::NewWindowDisposition, WindowOpenDisposition::NEW_WINDOW)
+ASSERT_ENUMS_MATCH(WebContentsAdapterClient::SaveToDiskDisposition, WindowOpenDisposition::SAVE_TO_DISK)
+ASSERT_ENUMS_MATCH(WebContentsAdapterClient::OffTheRecordDisposition, WindowOpenDisposition::OFF_THE_RECORD)
+ASSERT_ENUMS_MATCH(WebContentsAdapterClient::IgnoreActionDisposition, WindowOpenDisposition::IGNORE_ACTION)
+
} // namespace QtWebEngineCore
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index cb7f9b461..0accd3be5 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -168,7 +168,7 @@ public:
Qt::DropActions allowedActions, const QPixmap &pixmap, const QPoint &offset);
void enterDrag(QDragEnterEvent *e, const QPoint &screenPos);
Qt::DropAction updateDragPosition(QDragMoveEvent *e, const QPoint &screenPos);
- void updateDragAction(Qt::DropAction action);
+ void updateDragAction(int action);
void finishDragUpdate();
void endDragging(const QPoint &clientPos, const QPoint &screenPos);
void leaveDrag();
diff --git a/src/core/web_contents_adapter_p.h b/src/core/web_contents_adapter_p.h
index 23a1aaef4..9503b4401 100644
--- a/src/core/web_contents_adapter_p.h
+++ b/src/core/web_contents_adapter_p.h
@@ -55,6 +55,8 @@
#include <base/callback.h>
#include "base/memory/ref_counted.h"
+#include <ui/gfx/geometry/point.h>
+#include <third_party/WebKit/public/platform/WebDragOperation.h>
#include <QScopedPointer>
#include <QSharedPointer>
@@ -93,8 +95,10 @@ public:
quint64 nextRequestId;
int lastFindRequestId;
std::unique_ptr<content::DropData> currentDropData;
- Qt::DropAction currentDropAction;
+ blink::WebDragOperation currentDropAction;
bool inDragUpdateLoop;
+ gfx::Point lastDragClientPos;
+ gfx::Point lastDragScreenPos;
base::Closure dragUpdateLoopQuitClosure;
QScopedPointer<QTimer> updateDragCursorMessagePollingTimer;
};
diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp
index 0c4cf29d3..24c4e198f 100644
--- a/src/core/web_contents_view_qt.cpp
+++ b/src/core/web_contents_view_qt.cpp
@@ -203,17 +203,6 @@ Qt::DropActions toQtDropActions(blink::WebDragOperationsMask ops)
return result;
}
-Qt::DropAction toQt(blink::WebDragOperation op)
-{
- if (op == blink::WebDragOperationCopy)
- return Qt::CopyAction;
- if (op == blink::WebDragOperationLink)
- return Qt::LinkAction;
- if (op == blink::WebDragOperationMove || op == blink::WebDragOperationDelete)
- return Qt::MoveAction;
- return Qt::IgnoreAction;
-}
-
void WebContentsViewQt::StartDragging(const content::DropData &drop_data,
blink::WebDragOperationsMask allowed_ops,
const gfx::ImageSkia &image,
@@ -235,7 +224,7 @@ void WebContentsViewQt::StartDragging(const content::DropData &drop_data,
void WebContentsViewQt::UpdateDragCursor(blink::WebDragOperation dragOperation)
{
- m_client->webContentsAdapter()->updateDragAction(toQt(dragOperation));
+ m_client->webContentsAdapter()->updateDragAction(dragOperation);
}
void WebContentsViewQt::TakeFocus(bool reverse)
diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp
index 4f5023376..9681ad629 100644
--- a/src/core/web_event_factory.cpp
+++ b/src/core/web_event_factory.cpp
@@ -1259,5 +1259,14 @@ content::NativeWebKeyboardEvent WebEventFactory::toWebKeyboardEvent(QKeyEvent *e
const ushort* text = ev->text().utf16();
memcpy(&webKitEvent.text, text, std::min(sizeof(webKitEvent.text), size_t(ev->text().length() * 2)));
memcpy(&webKitEvent.unmodifiedText, text, std::min(sizeof(webKitEvent.unmodifiedText), size_t(ev->text().length() * 2)));
+
+ if (webKitEvent.windowsKeyCode == VK_RETURN) {
+ // This is the same behavior as GTK:
+ // We need to treat the enter key as a key press of character \r. This
+ // is apparently just how webkit handles it and what it expects.
+ webKitEvent.unmodifiedText[0] = '\r';
+ webKitEvent.text[0] = webKitEvent.unmodifiedText[0];
+ }
+
return webKitEvent;
}
diff --git a/src/src.pro b/src/src.pro
index 26abd52cc..7f8b39cd6 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -7,37 +7,32 @@ webengine_plugin.subdir = webengine/plugin
webengine_plugin.target = sub-webengine-plugin
webengine_plugin.depends = webengine
-SUBDIRS += core
+SUBDIRS += core \
+ process \
+ webengine \
+ webengine_plugin \
+ plugins
-!use?(gn) {
- SUBDIRS += process \
- webengine \
- webengine_plugin \
- plugins
+use?(spellchecker):!use?(native_spellchecker):!cross_compile {
+ SUBDIRS += qwebengine_convert_dict
+ qwebengine_convert_dict.subdir = tools/qwebengine_convert_dict
+ qwebengine_convert_dict.depends = core
+}
- # allow only desktop builds of qwebengine_convert_dict
- 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
- }
+isQMLTestSupportApiEnabled() {
+ webengine_testsupport_plugin.subdir = webengine/plugin/testsupport
+ webengine_testsupport_plugin.target = sub-webengine-testsupport-plugin
+ webengine_testsupport_plugin.depends = webengine
+ SUBDIRS += webengine_testsupport_plugin
+}
- isQMLTestSupportApiEnabled() {
- webengine_testsupport_plugin.subdir = webengine/plugin/testsupport
- webengine_testsupport_plugin.target = sub-webengine-testsupport-plugin
- webengine_testsupport_plugin.depends = webengine
- SUBDIRS += webengine_testsupport_plugin
- }
+!contains(WEBENGINE_CONFIG, no_ui_delegates) {
+ SUBDIRS += webengine/ui \
+ webengine/ui2
+}
- # FIXME: We probably want a bit more control over config options to tweak what to build/ship or not.
- # Another example of where this could be necessary is to make it easy to build proprietery codecs support.
- !contains(WEBENGINE_CONFIG, no_ui_delegates) {
- SUBDIRS += webengine/ui \
- webengine/ui2
- }
- qtHaveModule(widgets) {
- SUBDIRS += webenginewidgets
- plugins.depends = webenginewidgets
- }
+qtHaveModule(widgets) {
+ SUBDIRS += webenginewidgets
+ plugins.depends = webenginewidgets
}
diff --git a/src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro b/src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro
index 715081b5f..7bece36cd 100644
--- a/src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro
+++ b/src/tools/qwebengine_convert_dict/qwebengine_convert_dict.pro
@@ -1,12 +1,31 @@
option(host_build)
# Look for linking information produced by gyp for our target according to core_generated.gyp
-!include($$OUT_PWD/../../core/$$getConfigDir()/convert_dict_linking.pri) {
- error("Could not find the linking information that gyp should have generated.")
+use?(gn): linking_pri = $$OUT_PWD/../../core/$$getConfigDir()/convert_dict.pri
+else: linking_pri = $$OUT_PWD/../../core/$$getConfigDir()/convert_dict_linking.pri
+
+!include($$linking_pri) {
+ error("Could not find the linking information that gyp/gn should have generated.")
}
-# skip dummy main.cpp file
-OBJECTS =
+use?(gn){
+ isEmpty(NINJA_OBJECTS): error("Missing object files from QtWebEngineCore linking pri.")
+ isEmpty(NINJA_LFLAGS): error("Missing linker flags from QtWebEngineCore linking pri")
+ isEmpty(NINJA_ARCHIVES): error("Missing archive files from QtWebEngineCore linking pri")
+ isEmpty(NINJA_LIBS): error("Missing library files from QtWebEngineCore linking pri")
+ OBJECTS = $$eval($$list($$NINJA_OBJECTS))
+ linux {
+ LIBS_PRIVATE = -Wl,--start-group $$NINJA_ARCHIVES -Wl,--end-group
+ } else {
+ LIBS_PRIVATE = $$NINJA_ARCHIVES
+ }
+ LIBS_PRIVATE += $$NINJA_LIB_DIRS $$NINJA_LIBS
+ QMAKE_LFLAGS += $$NINJA_LFLAGS
+ POST_TARGETDEPS += $$NINJA_TARGETDEPS
+} else {
+ # skip dummy main.cpp file
+ OBJECTS =
+}
# Fixme: -Werror=unused-parameter in core
QMAKE_CXXFLAGS_WARN_ON =
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index 871428f33..162dbe1d7 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -42,6 +42,7 @@
#include "qquickwebenginedownloaditem_p.h"
#include "qquickwebenginedownloaditem_p_p.h"
#include "qquickwebengineprofile_p.h"
+#include "qquickwebenginescript_p.h"
#include "qquickwebenginesettings_p.h"
#include "qwebenginecookiestore.h"
@@ -49,6 +50,7 @@
#include "browser_context_adapter.h"
#include <qtwebenginecoreglobal.h>
+#include "renderer_host/user_resource_controller_host.h"
#include "web_engine_settings.h"
using QtWebEngineCore::BrowserContextAdapter;
@@ -229,6 +231,38 @@ void QQuickWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info
}
}
+void QQuickWebEngineProfilePrivate::userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script)
+{
+ Q_ASSERT(p && p->data);
+ QQuickWebEngineProfilePrivate *d = static_cast<QQuickWebEngineProfilePrivate *>(p->data);
+ QtWebEngineCore::UserResourceControllerHost *resourceController = d->browserContext()->userResourceController();
+ d->m_userScripts.append(script);
+ script->d_func()->bind(resourceController);
+}
+
+int QQuickWebEngineProfilePrivate::userScripts_count(QQmlListProperty<QQuickWebEngineScript> *p)
+{
+ Q_ASSERT(p && p->data);
+ QQuickWebEngineProfilePrivate *d = static_cast<QQuickWebEngineProfilePrivate *>(p->data);
+ return d->m_userScripts.count();
+}
+
+QQuickWebEngineScript *QQuickWebEngineProfilePrivate::userScripts_at(QQmlListProperty<QQuickWebEngineScript> *p, int idx)
+{
+ Q_ASSERT(p && p->data);
+ QQuickWebEngineProfilePrivate *d = static_cast<QQuickWebEngineProfilePrivate *>(p->data);
+ return d->m_userScripts.at(idx);
+}
+
+void QQuickWebEngineProfilePrivate::userScripts_clear(QQmlListProperty<QQuickWebEngineScript> *p)
+{
+ Q_ASSERT(p && p->data);
+ QQuickWebEngineProfilePrivate *d = static_cast<QQuickWebEngineProfilePrivate *>(p->data);
+ QtWebEngineCore::UserResourceControllerHost *resourceController = d->browserContext()->userResourceController();
+ resourceController->clearAllScripts(NULL);
+ d->m_userScripts.clear();
+}
+
/*!
\qmltype WebEngineProfile
\instantiates QQuickWebEngineProfile
@@ -851,4 +885,33 @@ QQuickWebEngineSettings *QQuickWebEngineProfile::settings() const
return d->settings();
}
+/*!
+ \qmlproperty list<WebEngineScript> WebEngineProfile::userScripts
+ \since 1.5
+
+ Returns the collection of WebEngineScripts that are injected into all pages that share
+ this profile.
+
+ \sa WebEngineScript
+*/
+
+/*!
+ \property QQuickWebEngineProfile::userScripts
+ \since 5.9
+
+ \brief the collection of scripts that are injected into all pages that share
+ this profile.
+
+ \sa QQuickWebEngineScript, QQmlListReference
+*/
+QQmlListProperty<QQuickWebEngineScript> QQuickWebEngineProfile::userScripts()
+{
+ Q_D(QQuickWebEngineProfile);
+ return QQmlListProperty<QQuickWebEngineScript>(this, d,
+ d->userScripts_append,
+ d->userScripts_count,
+ d->userScripts_at,
+ d->userScripts_clear);
+}
+
QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebengineprofile.h b/src/webengine/api/qquickwebengineprofile.h
index d0d925930..0155c954a 100644
--- a/src/webengine/api/qquickwebengineprofile.h
+++ b/src/webengine/api/qquickwebengineprofile.h
@@ -46,6 +46,7 @@
#include <QtCore/QObject>
#include <QtCore/QScopedPointer>
#include <QtCore/QString>
+#include <QtQml/QQmlListProperty>
namespace QtWebEngineCore {
class BrowserContextAdapter;
@@ -55,6 +56,7 @@ QT_BEGIN_NAMESPACE
class QQuickWebEngineDownloadItem;
class QQuickWebEngineProfilePrivate;
+class QQuickWebEngineScript;
class QQuickWebEngineSettings;
class QWebEngineCookieStore;
class QWebEngineUrlRequestInterceptor;
@@ -73,6 +75,7 @@ class Q_WEBENGINE_EXPORT QQuickWebEngineProfile : public QObject {
Q_PROPERTY(int httpCacheMaximumSize READ httpCacheMaximumSize WRITE setHttpCacheMaximumSize NOTIFY httpCacheMaximumSizeChanged FINAL)
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)
+ Q_PROPERTY(QQmlListProperty<QQuickWebEngineScript> userScripts READ userScripts FINAL REVISION 4)
public:
QQuickWebEngineProfile(QObject *parent = Q_NULLPTR);
@@ -136,6 +139,8 @@ public:
void setSpellCheckEnabled(bool enabled);
bool isSpellCheckEnabled() const;
+ QQmlListProperty<QQuickWebEngineScript> userScripts();
+
static QQuickWebEngineProfile *defaultProfile();
Q_SIGNALS:
diff --git a/src/webengine/api/qquickwebengineprofile_p.h b/src/webengine/api/qquickwebengineprofile_p.h
index 1ba1eb53f..1828f8085 100644
--- a/src/webengine/api/qquickwebengineprofile_p.h
+++ b/src/webengine/api/qquickwebengineprofile_p.h
@@ -80,12 +80,19 @@ public:
void downloadRequested(DownloadItemInfo &info) Q_DECL_OVERRIDE;
void downloadUpdated(const DownloadItemInfo &info) Q_DECL_OVERRIDE;
+ // QQmlListPropertyHelpers
+ static void userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script);
+ static int userScripts_count(QQmlListProperty<QQuickWebEngineScript> *p);
+ static QQuickWebEngineScript *userScripts_at(QQmlListProperty<QQuickWebEngineScript> *p, int idx);
+ static void userScripts_clear(QQmlListProperty<QQuickWebEngineScript> *p);
+
private:
friend class QQuickWebEngineViewPrivate;
QQuickWebEngineProfile *q_ptr;
QScopedPointer<QQuickWebEngineSettings> m_settings;
QSharedPointer<QtWebEngineCore::BrowserContextAdapter> m_browserContextRef;
QMap<quint32, QPointer<QQuickWebEngineDownloadItem> > m_ongoingDownloads;
+ QList<QQuickWebEngineScript *> m_userScripts;
};
QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebenginescript.cpp b/src/webengine/api/qquickwebenginescript.cpp
index 5d5173144..590faf4f3 100644
--- a/src/webengine/api/qquickwebenginescript.cpp
+++ b/src/webengine/api/qquickwebenginescript.cpp
@@ -37,8 +37,8 @@
**
****************************************************************************/
+#include "qquickwebenginescript.h"
#include "qquickwebenginescript_p.h"
-#include "qquickwebenginescript_p_p.h"
#include <QQmlFile>
#include <QtCore/QDebug>
@@ -48,6 +48,58 @@
using QtWebEngineCore::UserScript;
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QQuickWebEngineScript
+ \brief Enables the injection of scripts in the JavaScript engine.
+ \inmodule QtWebEngine
+ \since 5.9
+
+ The QQuickWebEngineScript type enables the programmatic injection of so called \e {user scripts} in
+ the JavaScript engine at different points, determined by injectionPoint, during the loading of
+ web content.
+
+ Scripts can be executed either in the main JavaScript \e world, along with the rest of the
+ JavaScript coming from the web contents, or in their own isolated world. While the DOM of the
+ page can be accessed from any world, JavaScript variables of a function defined in one world are
+ not accessible from a different one. The worldId property provides some predefined IDs for this
+ purpose.
+*/
+
+/*!
+ \enum QQuickWebEngineScript::InjectionPoint
+
+ The point in the loading process at which the script will be executed.
+
+ \value DocumentCreation
+ The script will be executed as soon as the document is created. This is not suitable for
+ any DOM operation.
+ \value DocumentReady
+ The script will run as soon as the DOM is ready. This is equivalent to the
+ \c DOMContentLoaded event firing in JavaScript.
+ \value Deferred
+ The script will run when the page load finishes, or 500 ms after the document is ready,
+ whichever comes first.
+*/
+
+/*!
+ \enum QQuickWebEngineScript::ScriptWorldId
+
+ The world ID defining which isolated world the script is executed in.
+
+ \value MainWorld
+ The world used by the page's web contents. It can be useful in order to expose custom
+ functionality to web contents in certain scenarios.
+ \value ApplicationWorld
+ The default isolated world used for application level functionality implemented in
+ JavaScript.
+ \value UserWorld
+ The first isolated world to be used by scripts set by users if the application is not
+ making use of more worlds. As a rule of thumb, if that functionality is exposed to the
+ application users, each individual script should probably get its own isolated world.
+*/
+
/*!
\qmltype WebEngineScript
\instantiates QQuickWebEngineScript
@@ -72,16 +124,26 @@ using QtWebEngineCore::UserScript;
attached to the web view.
*/
-QQuickWebEngineScript::QQuickWebEngineScript()
- : d_ptr(new QQuickWebEngineScriptPrivate)
+/*!
+ Constructs a new QQuickWebEngineScript with the parent \a parent.
+*/
+QQuickWebEngineScript::QQuickWebEngineScript(QObject *parent)
+ : QObject(parent)
+ , d_ptr(new QQuickWebEngineScriptPrivate)
{
d_ptr->q_ptr = this;
}
+/*!
+ \internal
+*/
QQuickWebEngineScript::~QQuickWebEngineScript()
{
}
+/*!
+ Returns the script object as string.
+*/
QString QQuickWebEngineScript::toString() const
{
Q_D(const QQuickWebEngineScript);
@@ -106,6 +168,14 @@ QString QQuickWebEngineScript::toString() const
}
/*!
+ \property QQuickWebEngineScript::name
+ \brief The name of the script.
+
+ Can be useful to retrieve a particular script from
+ QQuickWebEngineProfile::userScripts.
+*/
+
+/*!
\qmlproperty string WebEngineScript::name
The name of the script. Can be useful to retrieve a particular script from
@@ -118,6 +188,20 @@ QString QQuickWebEngineScript::name() const
}
/*!
+ \property QQuickWebEngineScript::sourceUrl
+ \brief The remote source location of the user script (if any).
+
+ Unlike \l sourceCode, this property allows referring to user scripts that
+ are not already loaded in memory, for instance, when stored on disk.
+
+ Setting this property will change the \l sourceCode of the script.
+
+ \note At present, only file-based sources are supported.
+
+ \sa QQuickWebEngineScript::sourceCode
+*/
+
+/*!
\qmlproperty url WebEngineScript::sourceUrl
This property holds the remote source location of the user script (if any).
@@ -138,6 +222,13 @@ QUrl QQuickWebEngineScript::sourceUrl() const
}
/*!
+ \property QQuickWebEngineScript::sourceCode
+ \brief The JavaScript source code of the user script.
+
+ \sa QQuickWebEngineScript::sourceUrl
+*/
+
+/*!
\qmlproperty string WebEngineScript::sourceCode
This property holds the JavaScript source code of the user script.
@@ -155,6 +246,13 @@ ASSERT_ENUMS_MATCH(QQuickWebEngineScript::DocumentReady, UserScript::DocumentLoa
ASSERT_ENUMS_MATCH(QQuickWebEngineScript::DocumentCreation, UserScript::DocumentElementCreation)
/*!
+ \property QQuickWebEngineScript::injectionPoint
+ \brief The point in the loading process at which the script will be executed.
+
+ The default value is \c Deferred.
+*/
+
+/*!
\qmlproperty enumeration WebEngineScript::injectionPoint
The point in the loading process at which the script will be executed.
@@ -177,6 +275,11 @@ QQuickWebEngineScript::InjectionPoint QQuickWebEngineScript::injectionPoint() co
}
/*!
+ \property QQuickWebEngineScript::worldId
+ \brief The world ID defining which isolated world the script is executed in.
+*/
+
+/*!
\qmlproperty enumeration WebEngineScript::worldId
The world ID defining which isolated world the script is executed in.
@@ -199,6 +302,15 @@ QQuickWebEngineScript::ScriptWorldId QQuickWebEngineScript::worldId() const
}
/*!
+ \property QQuickWebEngineScript::runOnSubframes
+ \brief Whether the script is executed on every frame or only on the main frame.
+
+ Set this property to \c true if the script is executed on every frame in the page, or \c false
+ if it is only run for the main frame.
+ The default value is \c{false}.
+*/
+
+/*!
\qmlproperty int WebEngineScript::runOnSubframes
Set this property to \c true if the script is executed on every frame in the page, or \c false
@@ -211,21 +323,20 @@ bool QQuickWebEngineScript::runOnSubframes() const
return d->coreScript.runsOnSubFrames();
}
-
-void QQuickWebEngineScript::setName(QString arg)
+void QQuickWebEngineScript::setName(const QString &name)
{
Q_D(QQuickWebEngineScript);
- if (arg == name())
+ if (name == QQuickWebEngineScript::name())
return;
d->aboutToUpdateUnderlyingScript();
- d->coreScript.setName(arg);
- Q_EMIT nameChanged(arg);
+ d->coreScript.setName(name);
+ Q_EMIT nameChanged(name);
}
-void QQuickWebEngineScript::setSourceCode(QString arg)
+void QQuickWebEngineScript::setSourceCode(const QString &code)
{
Q_D(QQuickWebEngineScript);
- if (arg == sourceCode())
+ if (code == sourceCode())
return;
// setting the source directly resets the sourceUrl
@@ -235,22 +346,22 @@ void QQuickWebEngineScript::setSourceCode(QString arg)
}
d->aboutToUpdateUnderlyingScript();
- d->coreScript.setSourceCode(arg);
- Q_EMIT sourceCodeChanged(arg);
+ d->coreScript.setSourceCode(code);
+ Q_EMIT sourceCodeChanged(code);
}
-void QQuickWebEngineScript::setSourceUrl(QUrl arg)
+void QQuickWebEngineScript::setSourceUrl(const QUrl &url)
{
Q_D(QQuickWebEngineScript);
- if (arg == sourceUrl())
+ if (url == sourceUrl())
return;
- d->m_sourceUrl = arg;
+ d->m_sourceUrl = url;
Q_EMIT sourceUrlChanged(d->m_sourceUrl);
- QFile f(QQmlFile::urlToLocalFileOrQrc(arg));
+ QFile f(QQmlFile::urlToLocalFileOrQrc(url));
if (!f.open(QIODevice::ReadOnly)) {
- qWarning() << "Can't open user script " << arg;
+ qWarning() << "Can't open user script " << url;
return;
}
@@ -260,36 +371,36 @@ void QQuickWebEngineScript::setSourceUrl(QUrl arg)
Q_EMIT sourceCodeChanged(source);
}
-void QQuickWebEngineScript::setInjectionPoint(QQuickWebEngineScript::InjectionPoint arg)
+void QQuickWebEngineScript::setInjectionPoint(QQuickWebEngineScript::InjectionPoint injectionPoint)
{
Q_D(QQuickWebEngineScript);
- if (arg == injectionPoint())
+ if (injectionPoint == QQuickWebEngineScript::injectionPoint())
return;
d->aboutToUpdateUnderlyingScript();
- d->coreScript.setInjectionPoint(static_cast<UserScript::InjectionPoint>(arg));
- Q_EMIT injectionPointChanged(arg);
+ d->coreScript.setInjectionPoint(static_cast<UserScript::InjectionPoint>(injectionPoint));
+ Q_EMIT injectionPointChanged(injectionPoint);
}
-void QQuickWebEngineScript::setWorldId(QQuickWebEngineScript::ScriptWorldId arg)
+void QQuickWebEngineScript::setWorldId(QQuickWebEngineScript::ScriptWorldId scriptWorldId)
{
Q_D(QQuickWebEngineScript);
- if (arg == worldId())
+ if (scriptWorldId == worldId())
return;
d->aboutToUpdateUnderlyingScript();
- d->coreScript.setWorldId(arg);
- Q_EMIT worldIdChanged(arg);
+ d->coreScript.setWorldId(scriptWorldId);
+ Q_EMIT worldIdChanged(scriptWorldId);
}
-void QQuickWebEngineScript::setRunOnSubframes(bool arg)
+void QQuickWebEngineScript::setRunOnSubframes(bool on)
{
Q_D(QQuickWebEngineScript);
- if (arg == runOnSubframes())
+ if (on == runOnSubframes())
return;
d->aboutToUpdateUnderlyingScript();
- d->coreScript.setRunsOnSubFrames(arg);
- Q_EMIT runOnSubframesChanged(arg);
+ d->coreScript.setRunsOnSubFrames(on);
+ Q_EMIT runOnSubframesChanged(on);
}
void QQuickWebEngineScript::timerEvent(QTimerEvent *e)
@@ -327,3 +438,5 @@ void QQuickWebEngineScriptPrivate::aboutToUpdateUnderlyingScript()
// Defer updates to the next event loop
m_basicTimer.start(0, q);
}
+
+QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebenginescript.h b/src/webengine/api/qquickwebenginescript.h
new file mode 100644
index 000000000..2cd4fadf1
--- /dev/null
+++ b/src/webengine/api/qquickwebenginescript.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKWEBENGINESCRIPT_H
+#define QQUICKWEBENGINESCRIPT_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qurl.h>
+#include <QtWebEngine/qtwebengineglobal.h>
+
+QT_BEGIN_NAMESPACE
+class QQuickWebEngineScriptPrivate;
+class QQuickWebEngineView;
+
+class Q_WEBENGINE_EXPORT QQuickWebEngineScript : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+ Q_PROPERTY(QUrl sourceUrl READ sourceUrl WRITE setSourceUrl NOTIFY sourceUrlChanged)
+ Q_PROPERTY(QString sourceCode READ sourceCode WRITE setSourceCode NOTIFY sourceCodeChanged)
+ Q_PROPERTY(InjectionPoint injectionPoint READ injectionPoint WRITE setInjectionPoint NOTIFY injectionPointChanged)
+ Q_PROPERTY(ScriptWorldId worldId READ worldId WRITE setWorldId NOTIFY worldIdChanged)
+ Q_PROPERTY(bool runOnSubframes READ runOnSubframes WRITE setRunOnSubframes NOTIFY runOnSubframesChanged)
+
+
+public:
+ enum InjectionPoint {
+ Deferred,
+ DocumentReady,
+ DocumentCreation
+ };
+ Q_ENUM(InjectionPoint)
+
+ enum ScriptWorldId {
+ MainWorld = 0,
+ ApplicationWorld,
+ UserWorld
+ };
+ Q_ENUM(ScriptWorldId)
+
+ QQuickWebEngineScript(QObject *parent = Q_NULLPTR);
+ ~QQuickWebEngineScript();
+ Q_INVOKABLE QString toString() const;
+
+ QString name() const;
+ QUrl sourceUrl() const;
+ QString sourceCode() const;
+ InjectionPoint injectionPoint() const;
+ ScriptWorldId worldId() const;
+ bool runOnSubframes() const;
+
+ void setName(const QString &name);
+ void setSourceUrl(const QUrl &url);
+ void setSourceCode(const QString &code);
+ void setInjectionPoint(InjectionPoint injectionPoint);
+ void setWorldId(ScriptWorldId scriptWorldId);
+ void setRunOnSubframes(bool on);
+
+Q_SIGNALS:
+ void nameChanged(const QString &name);
+ void sourceUrlChanged(const QUrl &url);
+ void sourceCodeChanged(const QString &code);
+ void injectionPointChanged(InjectionPoint injectionPoint);
+ void worldIdChanged(ScriptWorldId scriptWorldId);
+ void runOnSubframesChanged(bool on);
+
+protected:
+ void timerEvent(QTimerEvent *e) override;
+
+private:
+ friend class QQuickWebEngineProfilePrivate;
+ friend class QQuickWebEngineViewPrivate;
+ Q_DECLARE_PRIVATE(QQuickWebEngineScript)
+ QScopedPointer<QQuickWebEngineScriptPrivate> d_ptr;
+};
+QT_END_NAMESPACE
+
+#endif // QQUICKWEBENGINESCRIPT_H
diff --git a/src/webengine/api/qquickwebenginescript_p.h b/src/webengine/api/qquickwebenginescript_p.h
index 851ecd26b..30b47a654 100644
--- a/src/webengine/api/qquickwebenginescript_p.h
+++ b/src/webengine/api/qquickwebenginescript_p.h
@@ -51,75 +51,37 @@
// We mean it.
//
-#include <private/qtwebengineglobal_p.h>
-#include <QtCore/QObject>
-#include <QtCore/QUrl>
+#include "qquickwebenginescript.h"
-QT_BEGIN_NAMESPACE
-class QQuickWebEngineScriptPrivate;
-class QQuickWebEngineView;
+#include <QtCore/QBasicTimer>
+#include "user_script.h"
+#include "web_contents_adapter.h"
-class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineScript : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged FINAL)
- Q_PROPERTY(QUrl sourceUrl READ sourceUrl WRITE setSourceUrl NOTIFY sourceUrlChanged FINAL)
- Q_PROPERTY(QString sourceCode READ sourceCode WRITE setSourceCode NOTIFY sourceCodeChanged FINAL)
- Q_PROPERTY(InjectionPoint injectionPoint READ injectionPoint WRITE setInjectionPoint NOTIFY injectionPointChanged FINAL)
- Q_PROPERTY(ScriptWorldId worldId READ worldId WRITE setWorldId NOTIFY worldIdChanged FINAL)
- Q_PROPERTY(bool runOnSubframes READ runOnSubframes WRITE setRunOnSubframes NOTIFY runOnSubframesChanged FINAL)
+namespace QtWebEngineCore {
+class UserResourceControllerHost;
+class WebContentsAdapter;
+} // namespace
+QT_BEGIN_NAMESPACE
+class QQuickWebEngineScriptPrivate {
public:
- enum InjectionPoint {
- Deferred,
- DocumentReady,
- DocumentCreation
- };
- Q_ENUM(InjectionPoint)
-
- enum ScriptWorldId {
- MainWorld = 0,
- ApplicationWorld,
- UserWorld
- };
- Q_ENUM(ScriptWorldId)
-
- QQuickWebEngineScript();
- ~QQuickWebEngineScript();
- Q_INVOKABLE QString toString() const;
-
- QString name() const;
- QUrl sourceUrl() const;
- QString sourceCode() const;
- InjectionPoint injectionPoint() const;
- ScriptWorldId worldId() const;
- bool runOnSubframes() const;
+ Q_DECLARE_PUBLIC(QQuickWebEngineScript)
+ QQuickWebEngineScriptPrivate();
+ void aboutToUpdateUnderlyingScript();
+ void bind(QtWebEngineCore::UserResourceControllerHost *, QtWebEngineCore::WebContentsAdapter * = 0);
-public Q_SLOTS:
- void setName(QString arg);
- void setSourceUrl(QUrl arg);
- void setSourceCode(QString arg);
- void setInjectionPoint(InjectionPoint arg);
- void setWorldId(ScriptWorldId arg);
- void setRunOnSubframes(bool arg);
-
-Q_SIGNALS:
- void nameChanged(QString arg);
- void sourceUrlChanged(QUrl arg);
- void sourceCodeChanged(QString arg);
- void injectionPointChanged(InjectionPoint arg);
- void worldIdChanged(ScriptWorldId arg);
- void runOnSubframesChanged(bool arg);
-
-protected:
- void timerEvent(QTimerEvent *e) override;
+ QtWebEngineCore::UserScript coreScript;
+ QBasicTimer m_basicTimer;
+ QtWebEngineCore::UserResourceControllerHost *m_controllerHost;
+ QtWebEngineCore::WebContentsAdapter *m_adapter;
+ QUrl m_sourceUrl;
private:
- friend class QQuickWebEngineViewPrivate;
- Q_DECLARE_PRIVATE(QQuickWebEngineScript)
- QScopedPointer<QQuickWebEngineScriptPrivate> d_ptr;
+ QQuickWebEngineScript *q_ptr;
+
};
+
QT_END_NAMESPACE
#endif // QQUICKWEBENGINESCRIPT_P_H
diff --git a/src/webengine/api/qquickwebenginescript_p_p.h b/src/webengine/api/qquickwebenginescript_p_p.h
deleted file mode 100644
index 4525505c6..000000000
--- a/src/webengine/api/qquickwebenginescript_p_p.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKWEBENGINESCRIPT_P_P_H
-#define QQUICKWEBENGINESCRIPT_P_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qquickwebenginescript_p.h"
-
-#include <QtCore/QBasicTimer>
-#include "user_script.h"
-#include "web_contents_adapter.h"
-
-namespace QtWebEngineCore {
-class UserResourceControllerHost;
-class WebContentsAdapter;
-} // namespace
-
-QT_BEGIN_NAMESPACE
-
-class QQuickWebEngineScriptPrivate {
-public:
- Q_DECLARE_PUBLIC(QQuickWebEngineScript)
- QQuickWebEngineScriptPrivate();
- void aboutToUpdateUnderlyingScript();
- void bind(QtWebEngineCore::UserResourceControllerHost *, QtWebEngineCore::WebContentsAdapter * = 0);
-
- QtWebEngineCore::UserScript coreScript;
- QBasicTimer m_basicTimer;
- QtWebEngineCore::UserResourceControllerHost *m_controllerHost;
- QtWebEngineCore::WebContentsAdapter *m_adapter;
- QUrl m_sourceUrl;
-
-private:
- QQuickWebEngineScript *q_ptr;
-
-};
-
-QT_END_NAMESPACE
-
-#endif // QQUICKWEBENGINESCRIPT_P_P_H
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index a19f0be53..2db25584c 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -55,7 +55,7 @@
#include "qquickwebenginenewviewrequest_p.h"
#include "qquickwebengineprofile_p.h"
#include "qquickwebenginesettings_p.h"
-#include "qquickwebenginescript_p_p.h"
+#include "qquickwebenginescript_p.h"
#ifdef ENABLE_QML_TESTSUPPORT_API
#include "qquickwebenginetestsupport_p.h"
@@ -1527,8 +1527,13 @@ void QQuickWebEngineView::dragLeaveEvent(QDragLeaveEvent *e)
void QQuickWebEngineView::dragMoveEvent(QDragMoveEvent *e)
{
Q_D(QQuickWebEngineView);
- e->accept();
- d->adapter->updateDragPosition(e, mapToScreen(this, e->pos()));
+ Qt::DropAction dropAction = d->adapter->updateDragPosition(e, mapToScreen(this, e->pos()));
+ if (Qt::IgnoreAction == dropAction) {
+ e->ignore();
+ } else {
+ e->setDropAction(dropAction);
+ e->accept();
+ }
}
void QQuickWebEngineView::dropEvent(QDropEvent *e)
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index 27224fadd..92eb5d7de 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -52,7 +52,7 @@
//
#include <private/qtwebengineglobal_p.h>
-#include "qquickwebenginescript_p.h"
+#include "qquickwebenginescript.h"
#include <QQuickItem>
#include <QtGui/qcolor.h>
diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc
index c3d737384..ff35b45cf 100644
--- a/src/webengine/doc/src/qtwebengine-overview.qdoc
+++ b/src/webengine/doc/src/qtwebengine-overview.qdoc
@@ -197,11 +197,16 @@
\section1 Proxy Support
- 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
- QNetworkProxyFactory::usesSystemConfiguration() is enabled, the proxy settings are automatically
- retrieved from the system. Settings from an installed QNetworkProxyFactory will be ignored
- though.
+ Qt WebEngine uses the proxy settings from \l{Qt Network}, and forwards them to Chromium's
+ networking stack. If QNetworkProxy::applicationProxy is set, it will also be used for Qt
+ WebEngine. If QNetworkProxyFactory::usesSystemConfiguration() is enabled, the proxy settings
+ are automatically retrieved from the system. Settings from an installed QNetworkProxyFactory
+ will be ignored, though.
+
+ Not all properties of QNetworkProxy are supported by Qt WebEngine. That is,
+ QNetworkProxy::type(), QNetworkProxy::hostName() and QNetworkProxy::port() are taken into
+ account. All other proxy settings such as QNetworkProxy::rawHeader(), QNetworkProxy::user(), or
+ QNetworkProxy::password() are ignored.
If a proxy requires authentication, QWebEnginePage::proxyAuthenticationRequired is emitted.
For Qt Quick, a dialog is shown.
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.h b/src/webengine/render_widget_host_view_qt_delegate_quick.h
index 385a98a3c..7a08e915b 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h
@@ -74,6 +74,7 @@ public:
virtual void resize(int width, int height) Q_DECL_OVERRIDE;
virtual void move(const QPoint&) Q_DECL_OVERRIDE { }
virtual void inputMethodStateChanged(bool editorVisible) Q_DECL_OVERRIDE;
+ virtual void setInputMethodHints(Qt::InputMethodHints) Q_DECL_OVERRIDE { }
// The QtQuick view doesn't have a backbuffer of its own and doesn't need this
virtual void setClearColor(const QColor &) Q_DECL_OVERRIDE { }
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
index d0a5e480c..057b91c75 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
@@ -77,6 +77,7 @@ public:
virtual void resize(int width, int height) Q_DECL_OVERRIDE;
virtual void move(const QPoint &screenPos) Q_DECL_OVERRIDE;
virtual void inputMethodStateChanged(bool) Q_DECL_OVERRIDE {}
+ virtual void setInputMethodHints(Qt::InputMethodHints) Q_DECL_OVERRIDE { }
virtual void setClearColor(const QColor &) Q_DECL_OVERRIDE { }
private:
diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro
index 5fa49c77e..27239225b 100644
--- a/src/webengine/webengine.pro
+++ b/src/webengine/webengine.pro
@@ -45,6 +45,7 @@ HEADERS = \
api/qquickwebenginenewviewrequest_p.h \
api/qquickwebengineprofile.h \
api/qquickwebengineprofile_p.h \
+ api/qquickwebenginescript.h \
api/qquickwebenginescript_p.h \
api/qquickwebenginesettings_p.h \
api/qquickwebenginesingleton_p.h \
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 27268d26b..69ecbe160 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -323,6 +323,11 @@ void RenderWidgetHostViewQtDelegateWidget::inputMethodStateChanged(bool editorVi
qApp->inputMethod()->setVisible(editorVisible);
}
+void RenderWidgetHostViewQtDelegateWidget::setInputMethodHints(Qt::InputMethodHints hints)
+{
+ QQuickWidget::setInputMethodHints(hints);
+}
+
void RenderWidgetHostViewQtDelegateWidget::setClearColor(const QColor &color)
{
QQuickWidget::setClearColor(color);
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
index 68e6a176b..fb33c55c7 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
@@ -75,6 +75,7 @@ public:
virtual void resize(int width, int height) Q_DECL_OVERRIDE;
virtual void move(const QPoint &screenPos) Q_DECL_OVERRIDE;
virtual void inputMethodStateChanged(bool editorVisible) Q_DECL_OVERRIDE;
+ virtual void setInputMethodHints(Qt::InputMethodHints) Q_DECL_OVERRIDE;
virtual void setClearColor(const QColor &color) Q_DECL_OVERRIDE;
protected:
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index f9fd854cc..5cc0d18df 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -34,6 +34,7 @@
#include <QQmlListProperty>
#include <QtTest/QtTest>
#include <QtWebEngine/QQuickWebEngineProfile>
+#include <QtWebEngine/QQuickWebEngineScript>
#include <private/qquickwebengineview_p.h>
#include <private/qquickwebenginecertificateerror_p.h>
#include <private/qquickwebenginedialogrequests_p.h>
@@ -42,7 +43,6 @@
#include <private/qquickwebengineloadrequest_p.h>
#include <private/qquickwebenginenavigationrequest_p.h>
#include <private/qquickwebenginenewviewrequest_p.h>
-#include <private/qquickwebenginescript_p.h>
#include <private/qquickwebenginesettings_p.h>
#include <private/qquickwebenginesingleton_p.h>
#include <private/qquickwebenginecontextmenurequest_p.h>
diff --git a/tests/auto/quick/qmltests/data/tst_userScripts.qml b/tests/auto/quick/qmltests/data/tst_userScripts.qml
index 88fa6f6e3..e9a4eba99 100644
--- a/tests/auto/quick/qmltests/data/tst_userScripts.qml
+++ b/tests/auto/quick/qmltests/data/tst_userScripts.qml
@@ -61,6 +61,12 @@ Item {
}
TestWebEngineView {
+ id: webEngineView2
+ width: 400
+ height: 300
+ }
+
+ TestWebEngineView {
id: webEngineViewWithConditionalUserScripts
width: 400
height: 300
@@ -82,6 +88,7 @@ Item {
function init() {
webEngineView.url = "";
webEngineView.userScripts = [];
+ webEngineView.profile.userScripts = [];
}
function test_oneScript() {
@@ -173,5 +180,17 @@ Item {
webEngineView.waitForLoadSucceeded();
tryCompare(webEngineView, "title", "Test page with huge link area");
}
+
+ function test_profileWideScript() {
+ webEngineView.profile.userScripts = [ changeDocumentTitleScript ];
+
+ webEngineView.url = Qt.resolvedUrl("test1.html");
+ webEngineView.waitForLoadSucceeded();
+ compare(webEngineView.title, "New title");
+
+ webEngineView2.url = Qt.resolvedUrl("test1.html");
+ webEngineView2.waitForLoadSucceeded();
+ compare(webEngineView2.title, "New title");
+ }
}
}
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index 2ae699310..8df84e048 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -34,6 +34,7 @@
#include <QtGui/qpa/qwindowsysteminterface.h>
#include <QtQml/QQmlEngine>
#include <QtTest/QtTest>
+#include <QtWebEngine/QQuickWebEngineProfile>
#include <private/qquickwebengineview_p.h>
#include <functional>
@@ -77,6 +78,7 @@ private Q_SLOTS:
void inputEventForwardingDisabledWhenActiveFocusOnPressDisabled();
void changeLocale();
+ void userScripts();
private:
inline QQuickWebEngineView *newWebEngineView();
@@ -720,5 +722,28 @@ void tst_QQuickWebEngineView::changeLocale()
delete viewEN;
}
+void tst_QQuickWebEngineView::userScripts()
+{
+ QScopedPointer<QQuickWebEngineView> webEngineView1(newWebEngineView());
+ webEngineView1->setParentItem(m_window->contentItem());
+ QScopedPointer<QQuickWebEngineView> webEngineView2(newWebEngineView());
+ webEngineView2->setParentItem(m_window->contentItem());
+
+ QQmlListReference list(webEngineView1->profile(), "userScripts");
+ QQuickWebEngineScript script;
+ script.setSourceCode("document.title = 'New title';");
+ list.append(&script);
+
+ webEngineView1->setUrl(urlFromTestPath("html/basic_page.html"));
+ QVERIFY(waitForLoadSucceeded(webEngineView1.data()));
+ QTRY_COMPARE(webEngineView1->title(), QStringLiteral("New title"));
+
+ webEngineView2->setUrl(urlFromTestPath("html/basic_page.html"));
+ QVERIFY(waitForLoadSucceeded(webEngineView2.data()));
+ QTRY_COMPARE(webEngineView2->title(), QStringLiteral("New title"));
+
+ list.clear();
+}
+
QTEST_MAIN(tst_QQuickWebEngineView)
#include "tst_qquickwebengineview.moc"
diff --git a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
index fef92c311..e0765736e 100644
--- a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
+++ b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
@@ -1,4 +1,4 @@
include(../tests.pri)
-QT *= core-private gui-private
+QT *= core-private
contains(WEBENGINE_CONFIG, use_pdf): DEFINES+=QWEBENGINEPAGE_PDFPRINTINGENABLED
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 5467ce39e..7e78e2b0e 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -32,17 +32,15 @@
#include <QOpenGLWidget>
#include <QPaintEngine>
#include <QPushButton>
+#include <QScreen>
#include <QStateMachine>
-#include <QStyle>
#include <QtGui/QClipboard>
#include <QtTest/QtTest>
#include <QTextCharFormat>
#include <QWebChannel>
-#include <private/qinputmethod_p.h>
#include <qnetworkcookiejar.h>
#include <qnetworkreply.h>
#include <qnetworkrequest.h>
-#include <qpa/qplatforminputcontext.h>
#include <qwebenginedownloaditem.h>
#include <qwebenginefullscreenrequest.h>
#include <qwebenginehistory.h>
@@ -66,38 +64,6 @@ static void removeRecursive(const QString& dirname)
QDir().rmdir(dirname);
}
-class TestInputContext : public QPlatformInputContext
-{
-public:
- TestInputContext()
- : m_visible(false)
- {
- QInputMethodPrivate* inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
- inputMethodPrivate->testContext = this;
- }
-
- ~TestInputContext()
- {
- QInputMethodPrivate* inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
- inputMethodPrivate->testContext = 0;
- }
-
- virtual void showInputPanel()
- {
- m_visible = true;
- }
- virtual void hideInputPanel()
- {
- m_visible = false;
- }
- virtual bool isInputPanelVisible() const
- {
- return m_visible;
- }
-
- bool m_visible;
-};
-
class tst_QWebEnginePage : public QObject
{
Q_OBJECT
@@ -1671,24 +1637,6 @@ void tst_QWebEnginePage::inputMethods_data()
}
#if defined(QWEBENGINEPAGE_INPUTMETHODQUERY)
-static Qt::InputMethodHints inputMethodHints(QObject* object)
-{
- if (QGraphicsObject* o = qobject_cast<QGraphicsObject*>(object))
- return o->inputMethodHints();
- if (QWidget* w = qobject_cast<QWidget*>(object))
- return w->inputMethodHints();
- return Qt::InputMethodHints();
-}
-
-static bool inputMethodEnabled(QObject* object)
-{
- if (QGraphicsObject* o = qobject_cast<QGraphicsObject*>(object))
- return o->flags() & QGraphicsItem::ItemAcceptsInputMethod;
- if (QWidget* w = qobject_cast<QWidget*>(object))
- return w->testAttribute(Qt::WA_InputMethodEnabled);
- return false;
-}
-
static void clickOnPage(QWebEnginePage* page, const QPoint& position)
{
QMouseEvent evpres(QEvent::MouseButtonPress, position, Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
@@ -1741,32 +1689,6 @@ void tst_QWebEnginePage::inputMethods()
clickOnPage(page, textInputCenter);
- // This part of the test checks if the SIP (Software Input Panel) is triggered,
- // which normally happens on mobile platforms, when a user input form receives
- // a mouse click.
- int inputPanel = 0;
- if (viewType == "QWebEngineView") {
- if (QWebEngineView* wv = qobject_cast<QWebEngineView*>(view))
- inputPanel = wv->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel);
- } else if (viewType == "QGraphicsWebView") {
- if (QGraphicsWebView* wv = qobject_cast<QGraphicsWebView*>(view))
- inputPanel = wv->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel);
- }
-
- // For non-mobile platforms RequestSoftwareInputPanel event is not called
- // because there is no SIP (Software Input Panel) triggered. In the case of a
- // mobile platform, an input panel, e.g. virtual keyboard, is usually invoked
- // and the RequestSoftwareInputPanel event is called. For these two situations
- // this part of the test can verified as the checks below.
- if (inputPanel)
- QVERIFY(testContext.isInputPanelVisible());
- else
- QVERIFY(!testContext.isInputPanelVisible());
- testContext.hideInputPanel();
-
- clickOnPage(page, textInputCenter);
- QVERIFY(testContext.isInputPanelVisible());
-
//ImMicroFocus
QVariant variant = page->inputMethodQuery(Qt::ImMicroFocus);
QVERIFY(inputs.at(0).geometry().contains(variant.toRect().topLeft()));
@@ -1960,38 +1882,6 @@ void tst_QWebEnginePage::inputMethods()
//END - Tests for Selection when the Editor is not in Composition mode
- //ImhHiddenText
- QPoint passwordInputCenter = inputs.at(1).geometry().center();
- clickOnPage(page, passwordInputCenter);
-
- QVERIFY(inputMethodEnabled(view));
- QVERIFY(inputMethodHints(view) & Qt::ImhHiddenText);
-
- clickOnPage(page, textInputCenter);
- QVERIFY(!(inputMethodHints(view) & Qt::ImhHiddenText));
-
- page->setHtml("<html><body><p>nothing to input here");
- testContext.hideInputPanel();
-
- QWebEngineElement para = page->mainFrame()->findFirstElement("p");
- clickOnPage(page, para.geometry().center());
-
- QVERIFY(!testContext.isInputPanelVisible());
-
- //START - Test for sending empty QInputMethodEvent
- page->setHtml("<html><body>" \
- "<input type='text' id='input3' value='QtWebEngine2'/>" \
- "</body></html>");
- evaluateJavaScriptSync(page, "var inputEle = document.getElementById('input3'); inputEle.focus(); inputEle.select();");
-
- //Send empty QInputMethodEvent
- QInputMethodEvent emptyEvent;
- page->event(&emptyEvent);
-
- QString inputValue = evaluateJavaScriptSync(page, "document.getElementById('input3').value").toString();
- QCOMPARE(inputValue, QString("QtWebEngine2"));
- //END - Test for sending empty QInputMethodEvent
-
page->setHtml("<html><body>" \
"<input type='text' id='input4' value='QtWebEngine inputMethod'/>" \
"</body></html>");
@@ -2299,98 +2189,6 @@ void tst_QWebEnginePage::inputMethods()
variant = page->inputMethodQuery(Qt::ImAnchorPosition);
anchorPosition = variant.toInt();
QCOMPARE(anchorPosition, 12);
-
- // Check sending RequestSoftwareInputPanel event
- page->setHtml("<html><body>" \
- "<input type='text' id='input5' value='QtWebEngine inputMethod'/>" \
- "<div id='btnDiv' onclick='i=document.getElementById(&quot;input5&quot;); i.focus();'>abc</div>"\
- "</body></html>");
- QWebEngineElement inputElement = page->mainFrame()->findFirstElement("div");
- clickOnPage(page, inputElement.geometry().center());
-
- QVERIFY(!testContext.isInputPanelVisible());
-
- // START - Newline test for textarea
- qApp->processEvents();
- page->setHtml("<html><body>" \
- "<textarea rows='5' cols='1' id='input5' value=''/>" \
- "</body></html>");
- evaluateJavaScriptSync(page, "var inputEle = document.getElementById('input5'); inputEle.focus(); inputEle.select();");
-
- // Enter Key without key text
- QKeyEvent keyEnter(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
- page->event(&keyEnter);
- QList<QInputMethodEvent::Attribute> attribs;
-
- QInputMethodEvent eventText(QString(), attribs);
- eventText.setCommitString("\n");
- page->event(&eventText);
-
- QInputMethodEvent eventText2(QString(), attribs);
- eventText2.setCommitString("third line");
- page->event(&eventText2);
- qApp->processEvents();
-
- QString inputValue2 = evaluateJavaScriptSync(page, "document.getElementById('input5').value").toString();
- QCOMPARE(inputValue2, QString("\n\nthird line"));
-
- // Enter Key with key text '\r'
- evaluateJavaScriptSync(page, "var inputEle = document.getElementById('input5'); inputEle.value = ''; inputEle.focus(); inputEle.select();");
- inputValue2 = evaluateJavaScriptSync(page, "document.getElementById('input5').value").toString();
- QCOMPARE(inputValue2, QString(""));
-
- QKeyEvent keyEnterWithCarriageReturn(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier, "\r");
- page->event(&keyEnterWithCarriageReturn);
- page->event(&eventText);
- page->event(&eventText2);
- qApp->processEvents();
-
- inputValue2 = evaluateJavaScriptSync(page, "document.getElementById('input5').value").toString();
- QCOMPARE(inputValue2, QString("\n\nthird line"));
-
- // Enter Key with key text '\n'
- page->runJavaScript("var inputEle = document.getElementById('input5'); inputEle.value = ''; inputEle.focus(); inputEle.select();");
- inputValue2 = evaluateJavaScriptSync(page, "document.getElementById('input5').value").toString();
- QCOMPARE(inputValue2, QString(""));
-
- QKeyEvent keyEnterWithLineFeed(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier, "\n");
- page->event(&keyEnterWithLineFeed);
- page->event(&eventText);
- page->event(&eventText2);
- qApp->processEvents();
-
- inputValue2 = evaluateJavaScriptSync(page, "document.getElementById('input5').value").toString();
- QCOMPARE(inputValue2, QString("\n\nthird line"));
-
- // Enter Key with key text "\n\r"
- page->runJavaScript("var inputEle = document.getElementById('input5'); inputEle.value = ''; inputEle.focus(); inputEle.select();");
- inputValue2 = evaluateJavaScriptSync(page, "document.getElementById('input5').value").toString();
- QCOMPARE(inputValue2, QString(""));
-
- QKeyEvent keyEnterWithLFCR(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier, "\n\r");
- page->event(&keyEnterWithLFCR);
- page->event(&eventText);
- page->event(&eventText2);
- qApp->processEvents();
-
- inputValue2 = evaluateJavaScriptSync(page, "document.getElementById('input5').value").toString();
- QCOMPARE(inputValue2, QString("\n\nthird line"));
-
- // Return Key without key text
- page->runJavaScript("var inputEle = document.getElementById('input5'); inputEle.value = ''; inputEle.focus(); inputEle.select();");
- inputValue2 = evaluateJavaScriptSync(page, "document.getElementById('input5').value").toString();
- QCOMPARE(inputValue2, QString(""));
-
- QKeyEvent keyReturn(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier);
- page->event(&keyReturn);
- page->event(&eventText);
- page->event(&eventText2);
- qApp->processEvents();
-
- inputValue2 = evaluateJavaScriptSync(page, "document.getElementById('input5').value").toString();
- QCOMPARE(inputValue2, QString("\n\nthird line"));
-
- // END - Newline test for textarea
#endif
}
diff --git a/tests/auto/widgets/qwebengineview/qwebengineview.pro b/tests/auto/widgets/qwebengineview/qwebengineview.pro
index e99c7f493..d91c0074b 100644
--- a/tests/auto/widgets/qwebengineview/qwebengineview.pro
+++ b/tests/auto/widgets/qwebengineview/qwebengineview.pro
@@ -1 +1,2 @@
include(../tests.pri)
+QT *= gui-private
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 53c7650fb..b173c3474 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -22,8 +22,10 @@
#include <qtest.h>
#include "../util.h"
+#include <private/qinputmethod_p.h>
#include <qpainter.h>
#include <qpagelayout.h>
+#include <qpa/qplatforminputcontext.h>
#include <qwebengineview.h>
#include <qwebenginepage.h>
#include <qwebenginesettings.h>
@@ -39,6 +41,7 @@
#include <QtWebEngineCore/qwebenginehttprequest.h>
#include <QTcpServer>
#include <QTcpSocket>
+#include <QStyle>
#define VERIFY_INPUTMETHOD_HINTS(actual, expect) \
QVERIFY(actual == expect);
@@ -91,6 +94,11 @@ private Q_SLOTS:
void keyboardEvents();
void keyboardFocusAfterPopup();
void postData();
+
+ void softwareInputPanel();
+ void hiddenText();
+ void emptyInputMethodEvent();
+ void newlineInTextarea();
};
// This will be called before the first test function is executed.
@@ -1216,5 +1224,264 @@ void tst_QWebEngineView::postData()
server.close();
}
+class TestInputContext : public QPlatformInputContext
+{
+public:
+ TestInputContext()
+ : m_visible(false)
+ {
+ QInputMethodPrivate* inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
+ inputMethodPrivate->testContext = this;
+ }
+
+ ~TestInputContext()
+ {
+ QInputMethodPrivate* inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
+ inputMethodPrivate->testContext = 0;
+ }
+
+ virtual void showInputPanel()
+ {
+ m_visible = true;
+ }
+ virtual void hideInputPanel()
+ {
+ m_visible = false;
+ }
+ virtual bool isInputPanelVisible() const
+ {
+ return m_visible;
+ }
+
+ bool m_visible;
+};
+
+static QPoint elementCenter(QWebEnginePage *page, const QString &id)
+{
+ const QString jsCode(
+ "(function(){"
+ " var elem = document.getElementById('" + id + "');"
+ " var rect = elem.getBoundingClientRect();"
+ " return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2];"
+ "})()");
+ QVariantList rectList = evaluateJavaScriptSync(page, jsCode).toList();
+
+ if (rectList.count() != 2) {
+ qWarning("elementCenter failed.");
+ return QPoint();
+ }
+
+ return QPoint(rectList.at(0).toInt(), rectList.at(1).toInt());
+}
+
+void tst_QWebEngineView::softwareInputPanel()
+{
+ TestInputContext testContext;
+ QWebEngineView view;
+ view.show();
+
+ QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+ view.setHtml("<html><body>"
+ " <input type='text' id='input1' value='' size='50'/>"
+ "</body></html>");
+ QVERIFY(loadFinishedSpy.wait());
+
+ QPoint textInputCenter = elementCenter(view.page(), "input1");
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
+
+ // This part of the test checks if the SIP (Software Input Panel) is triggered,
+ // which normally happens on mobile platforms, when a user input form receives
+ // a mouse click.
+ int inputPanel = view.style()->styleHint(QStyle::SH_RequestSoftwareInputPanel);
+
+ // For non-mobile platforms RequestSoftwareInputPanel event is not called
+ // because there is no SIP (Software Input Panel) triggered. In the case of a
+ // mobile platform, an input panel, e.g. virtual keyboard, is usually invoked
+ // and the RequestSoftwareInputPanel event is called. For these two situations
+ // this part of the test can verified as the checks below.
+ if (inputPanel)
+ QTRY_VERIFY(testContext.isInputPanelVisible());
+ else
+ QTRY_VERIFY(!testContext.isInputPanelVisible());
+ testContext.hideInputPanel();
+
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTRY_VERIFY(testContext.isInputPanelVisible());
+
+ view.setHtml("<html><body><p id='para'>nothing to input here</p></body></html>");
+ QVERIFY(loadFinishedSpy.wait());
+ testContext.hideInputPanel();
+
+ QPoint paraCenter = elementCenter(view.page(), "para");
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, paraCenter);
+
+ QVERIFY(!testContext.isInputPanelVisible());
+
+ // Check sending RequestSoftwareInputPanel event
+ view.page()->setHtml("<html><body>"
+ " <input type='text' id='input1' value='QtWebEngine inputMethod'/>"
+ " <div id='btnDiv' onclick='i=document.getElementById(&quot;input1&quot;); i.focus();'>abc</div>"
+ "</body></html>");
+ QVERIFY(loadFinishedSpy.wait());
+
+ QPoint btnDivCenter = elementCenter(view.page(), "btnDiv");
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, btnDivCenter);
+
+ QVERIFY(!testContext.isInputPanelVisible());
+}
+
+void tst_QWebEngineView::hiddenText()
+{
+ QWebEngineView view;
+ view.show();
+
+ QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+ view.setHtml("<html><body>"
+ " <input type='text' id='input1' value='QtWebEngine' size='50'/><br>"
+ " <input type='password' id='password1'/>"
+ "</body></html>");
+ QVERIFY(loadFinishedSpy.wait());
+
+ QPoint passwordInputCenter = elementCenter(view.page(), "password1");
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, passwordInputCenter);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("password1"));
+
+ QVERIFY(view.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
+ QVERIFY(view.focusProxy()->inputMethodHints() & Qt::ImhHiddenText);
+
+ QPoint textInputCenter = elementCenter(view.page(), "input1");
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
+ QVERIFY(!(view.focusProxy()->inputMethodHints() & Qt::ImhHiddenText));
+}
+
+void tst_QWebEngineView::emptyInputMethodEvent()
+{
+ QWebEngineView view;
+ view.show();
+
+ QSignalSpy selectionChangedSpy(&view, SIGNAL(selectionChanged()));
+ QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+ view.setHtml("<html><body>"
+ " <input type='text' id='input1' value='QtWebEngine'/>"
+ "</body></html>");
+ QVERIFY(loadFinishedSpy.wait());
+
+ evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.focus(); inputEle.select();");
+ QTRY_VERIFY(!evaluateJavaScriptSync(view.page(), "window.getSelection().toString()").toString().isEmpty());
+
+ QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue);
+ QVERIFY(selectionChangedSpy.wait(100));
+ QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue);
+ QCOMPARE(selectionChangedSpy.count(), 1);
+
+ // Send empty QInputMethodEvent
+ QInputMethodEvent emptyEvent;
+ QApplication::sendEvent(view.focusProxy(), &emptyEvent);
+
+ QString inputValue = evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString();
+ QCOMPARE(inputValue, QString("QtWebEngine"));
+}
+
+void tst_QWebEngineView::newlineInTextarea()
+{
+ QWebEngineView view;
+ view.show();
+
+ QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+ view.page()->setHtml("<html><body>"
+ " <textarea rows='5' cols='1' id='input1'></textarea>"
+ "</body></html>");
+ QVERIFY(loadFinishedSpy.wait());
+
+ evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.focus(); inputEle.select();");
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString().isEmpty());
+
+ // Enter Key without key text
+ QKeyEvent keyPressEnter(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
+ QKeyEvent keyReleaseEnter(QEvent::KeyRelease, Qt::Key_Enter, Qt::NoModifier);
+ QApplication::sendEvent(view.focusProxy(), &keyPressEnter);
+ QApplication::sendEvent(view.focusProxy(), &keyReleaseEnter);
+
+ QList<QInputMethodEvent::Attribute> attribs;
+
+ QInputMethodEvent eventText(QString(), attribs);
+ eventText.setCommitString("\n");
+ QApplication::sendEvent(view.focusProxy(), &eventText);
+
+ QInputMethodEvent eventText2(QString(), attribs);
+ eventText2.setCommitString("third line");
+ QApplication::sendEvent(view.focusProxy(), &eventText2);
+
+ qApp->processEvents();
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), QString("\n\nthird line"));
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("\n\nthird line"));
+
+ // Enter Key with key text '\r'
+ evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.value = ''; inputEle.focus(); inputEle.select();");
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString().isEmpty());
+
+ QKeyEvent keyPressEnterWithCarriageReturn(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier, "\r");
+ QKeyEvent keyReleaseEnterWithCarriageReturn(QEvent::KeyRelease, Qt::Key_Enter, Qt::NoModifier);
+ QApplication::sendEvent(view.focusProxy(), &keyPressEnterWithCarriageReturn);
+ QApplication::sendEvent(view.focusProxy(), &keyReleaseEnterWithCarriageReturn);
+
+ QApplication::sendEvent(view.focusProxy(), &eventText);
+ QApplication::sendEvent(view.focusProxy(), &eventText2);
+
+ qApp->processEvents();
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), QString("\n\nthird line"));
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("\n\nthird line"));
+
+ // Enter Key with key text '\n'
+ evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.value = ''; inputEle.focus(); inputEle.select();");
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString().isEmpty());
+
+ QKeyEvent keyPressEnterWithLineFeed(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier, "\n");
+ QKeyEvent keyReleaseEnterWithLineFeed(QEvent::KeyRelease, Qt::Key_Enter, Qt::NoModifier, "\n");
+ QApplication::sendEvent(view.focusProxy(), &keyPressEnterWithLineFeed);
+ QApplication::sendEvent(view.focusProxy(), &keyReleaseEnterWithLineFeed);
+
+ QApplication::sendEvent(view.focusProxy(), &eventText);
+ QApplication::sendEvent(view.focusProxy(), &eventText2);
+
+ qApp->processEvents();
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), QString("\n\nthird line"));
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("\n\nthird line"));
+
+ // Enter Key with key text "\n\r"
+ evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.value = ''; inputEle.focus(); inputEle.select();");
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString().isEmpty());
+
+ QKeyEvent keyPressEnterWithLFCR(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier, "\n\r");
+ QKeyEvent keyReleaseEnterWithLFCR(QEvent::KeyRelease, Qt::Key_Enter, Qt::NoModifier, "\n\r");
+ QApplication::sendEvent(view.focusProxy(), &keyPressEnterWithLFCR);
+ QApplication::sendEvent(view.focusProxy(), &keyReleaseEnterWithLFCR);
+
+ QApplication::sendEvent(view.focusProxy(), &eventText);
+ QApplication::sendEvent(view.focusProxy(), &eventText2);
+
+ qApp->processEvents();
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), QString("\n\nthird line"));
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("\n\nthird line"));
+
+ // Return Key without key text
+ evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.value = ''; inputEle.focus(); inputEle.select();");
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString().isEmpty());
+
+ QKeyEvent keyPressReturn(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
+ QKeyEvent keyReleaseReturn(QEvent::KeyRelease, Qt::Key_Enter, Qt::NoModifier);
+ QApplication::sendEvent(view.focusProxy(), &keyPressReturn);
+ QApplication::sendEvent(view.focusProxy(), &keyReleaseReturn);
+
+ QApplication::sendEvent(view.focusProxy(), &eventText);
+ QApplication::sendEvent(view.focusProxy(), &eventText2);
+
+ qApp->processEvents();
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), QString("\n\nthird line"));
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("\n\nthird line"));
+}
+
QTEST_MAIN(tst_QWebEngineView)
#include "tst_qwebengineview.moc"
diff --git a/tools/qmake/mkspecs/features/configure.prf b/tools/qmake/mkspecs/features/configure.prf
index 759638877..48a1eb263 100644
--- a/tools/qmake/mkspecs/features/configure.prf
+++ b/tools/qmake/mkspecs/features/configure.prf
@@ -28,6 +28,12 @@ defineTest(runConfigure) {
qtConfig(printing-and-pdf): WEBENGINE_CONFIG += use_printing use_pdf
qtConfig(proprietary-codecs): WEBENGINE_CONFIG += use_proprietary_codecs
qtConfig(spellchecker): WEBENGINE_CONFIG += use_spellchecker
+ qtConfig(webrtc): WEBENGINE_CONFIG += use_webrtc
+ qtConfig(embedded): WEBENGINE_CONFIG += embedded_build
+ } else {
+ cross_compile: WEBENGINE_CONFIG += embedded_build
+ }
+ isQtMinimum(5, 9) {
qtConfig(appstore-compliant): WEBENGINE_CONFIG += use_appstore_compliant_code
}
@@ -36,14 +42,14 @@ defineTest(runConfigure) {
!config_khr:skipBuild("khronos development headers appear to be missing (mesa/libegl1-mesa-dev)")
REQUIRED_PACKAGES = dbus-1 fontconfig
- !cross_compile: qtConfig(xcb): REQUIRED_PACKAGES += libdrm xcomposite xcursor xi xrandr xscrnsaver xtst
+ !contains(WEBENGINE_CONFIG, embedded_build): qtConfig(xcb): REQUIRED_PACKAGES += libdrm xcomposite xcursor xi xrandr xscrnsaver xtst
qtConfig(pulseaudio): REQUIRED_PACKAGES += libpulse
qtConfig(system-png): REQUIRED_PACKAGES += libpng
qtConfig(system-harfbuzz) {
packagesExist("\'harfbuzz >= 1.2.0\'"): WEBENGINE_CONFIG += use_system_harfbuzz
else: log("System harfbuzz is too old (min. version 1.2). Using Chromium's copy.$${EOL}")
}
- !cross_compile: REQUIRED_PACKAGES += libpci
+ !contains(WEBENGINE_CONFIG, embedded_build): REQUIRED_PACKAGES += libpci
for(package, $$list($$REQUIRED_PACKAGES)) {
!packagesExist($$package):skipBuild("Unmet dependency: $$package")
@@ -84,7 +90,7 @@ defineTest(runConfigure) {
WEBENGINE_CONFIG += use_bundled_snappy
}
- !cross_compile {
+ !contains(WEBENGINE_CONFIG, embedded_build) {
packagesExist(nss): WEBENGINE_CONFIG += use_nss
else: log("System NSS not found, BoringSSL will be used.$${EOL}")
}
diff --git a/tools/qmake/mkspecs/features/functions.prf b/tools/qmake/mkspecs/features/functions.prf
index a47e4b7e8..f3c2eb905 100644
--- a/tools/qmake/mkspecs/features/functions.prf
+++ b/tools/qmake/mkspecs/features/functions.prf
@@ -260,6 +260,11 @@ defineTest(isMinWinSDKVersion) {
requested_minor = $$2
WIN_SDK_VERSION = $$(WindowsSDKVersion)
+ isEmpty(WIN_SDK_VERSION)|equals(WIN_SDK_VERSION, "\\") {
+ skipBuild("Could not detect Windows SDK version (\'WindowsSDKVersion\' environment variable is not set).")
+ return(false)
+ }
+
# major.0.minor
major_version = $$section(WIN_SDK_VERSION, ., 0, 0)
minor_version = $$section(WIN_SDK_VERSION, ., 2, 2)
@@ -381,19 +386,23 @@ defineReplace(buildNinja) {
!exists($$out) {
mkpath($$dirname(out))
src_3rd_party_dir = $$absolute_path("$${getChromiumSrcDir()}/../", "$$QTWEBENGINE_ROOT")
- ninja_configure = $$absolute_path(ninja/configure.py, $$src_3rd_party_dir)
- system("cd $$system_quote($$system_path($$dirname(out))) && python $$system_quote($$system_path($$ninja_configure)) --bootstrap")
+ ninja_configure = $$system_quote($$system_path($$absolute_path(ninja/configure.py, $$src_3rd_party_dir)))
+ !system("cd $$system_quote($$system_path($$dirname(out))) && python $$ninja_configure --bootstrap") {
+ error("NINJA build error!")
+ }
}
}
defineReplace(gnPath) {
src_3rd_party_dir = $$absolute_path("$${getChromiumSrcDir()}/../", "$$QTWEBENGINE_ROOT")
- out = $$shadowed($$absolute_path(chromium/tools/gn/gn, $$src_3rd_party_dir))
+ out = $$shadowed($$absolute_path(chromium/tools/gn/out/Release/gn, $$src_3rd_party_dir))
+
win32: out = $${out}.exe
return($$out)
}
defineReplace(buildGn) {
+ gn_args = $$1
out = $$gnPath()
!qtConfig(system-ninja): ninja_path = "--path $$ninjaPath()"
# check if it is not already build
@@ -401,9 +410,11 @@ defineReplace(buildGn) {
mkpath($$dirname(out))
src_3rd_party_dir = $$absolute_path("$${getChromiumSrcDir()}/../", "$$QTWEBENGINE_ROOT")
gn_bootstrap = $$system_path($$absolute_path(chromium/tools/gn/bootstrap/bootstrap.py, $$src_3rd_party_dir))
- gn_args = $$system_quote(is_clang=false use_sysroot=false enable_remoting=false enable_nacl=false)
+ gn_args = $$system_quote($$gn_args)
gn_configure = $$system_quote($$gn_bootstrap) --shadow --gn-gen-args=$$gn_args $$ninja_path
- system("cd $$system_quote($$system_path($$dirname(out))) && python $$gn_configure")
+ !system("cd $$system_quote($$system_path($$dirname(out))) && python $$gn_configure") {
+ error("GN build error!")
+ }
}
}
diff --git a/tools/qmake/mkspecs/features/gn_generator.prf b/tools/qmake/mkspecs/features/gn_generator.prf
index c5f283a99..ccc2831ae 100644
--- a/tools/qmake/mkspecs/features/gn_generator.prf
+++ b/tools/qmake/mkspecs/features/gn_generator.prf
@@ -10,6 +10,18 @@ defineReplace(getTargetType) {
return("none")
}
+defineReplace(filter_flag_values) {
+ value_to_check = $$1
+ macos:equals(value_to_check, "$(EXPORT_ARCH_ARGS)") {
+ # EXPORT_ARCH_ARGS comes from qtbase/mkspecs/features/mac/default_post.prf which is a way
+ # to figure out the architectures to pass to the compiler at Makefile time. Because this
+ # variable expansion is not supported by GN, we filter it out. GN takes care of assigning
+ # the architecture itself.
+ return("")
+ }
+ return($$value_to_check)
+}
+
isEmpty(GN_FILE): GN_FILE = $$system_path($$_PRO_FILE_PWD_/BUILD.gn)
isEmpty(GN_RUN_BINARY_SCRIPT): GN_RUN_BINARY_SCRIPT = "//build/gn_run_binary.py"
isEmpty(GN_FIND_MOCABLES_SCRIPT): GN_FIND_MOCABLES_SCRIPT = "//build/gn_find_mocables.py"
@@ -93,7 +105,7 @@ GN_CONTENTS += "}"
TARGET_TYPE = $$getTargetType()
GN_CONTENTS += "$${TARGET_TYPE}(\"$$TARGET\") {"
-
+!isEmpty(GN_CREATE_PRI): GN_CONTENTS += " create_pri_file = $$GN_CREATE_PRI"
!isEmpty(GN_IMPORTS) {
for (imp, GN_IMPORTS): GN_CONTENTS += " import(\"$$imp\")"
}
@@ -106,12 +118,19 @@ for (imp, GN_IMPORTS): GN_CONTENTS += " import(\"$$imp\")"
!isEmpty(QMAKE_CFLAGS) {
GN_CONTENTS += " cflags = ["
- for(flag, QMAKE_CFLAGS): GN_CONTENTS += " \"$$flag\","
+ for(flag, QMAKE_CFLAGS): GN_CONTENTS += " \"$$filter_flag_values($$flag)\","
GN_CONTENTS += " ]"
}
+
+# Stop the barrage of unused variables warnings.
+gcc|clang {
+ QMAKE_CXXFLAGS += "-Wno-unused-parameter"
+ QMAKE_CXXFLAGS += "-Wno-unused-variable"
+}
+
!isEmpty(QMAKE_CXXFLAGS) {
GN_CONTENTS += " cflags_cc = ["
- for(flag, QMAKE_CXXFLAGS): GN_CONTENTS += " \"$$flag\","
+ for(flag, QMAKE_CXXFLAGS): GN_CONTENTS += " \"$$filter_flag_values($$flag)\","
GN_CONTENTS += " ]"
}
@@ -119,7 +138,9 @@ GN_CONTENTS += " if (!defined(defines)) {"\
" defines = []"\
" }"
GN_CONTENTS += " defines += ["
-for (define, DEFINES): GN_CONTENTS += " \"$$define\","
+# Remove single quotes around function macro defines, so that GN doesn't escape them, thus breaking
+# the macro.
+for (define, DEFINES): GN_CONTENTS += " \"$$replace(define,\',)\","
!isEmpty(QMAKE_LIBDIR_EGL):
GN_CONTENTS += " \"QT_LIBDIR_EGL=\\\"$${QMAKE_DIR_SEP}$$relative_path($$QMAKE_LIBDIR_EGL, $$[QT_SYSROOT])\\\"\","
!isEmpty(QMAKE_LIBDIR_OPENGL_ES2)
@@ -147,9 +168,12 @@ GN_CONTENTS += " if (!defined(ldflags)) {"\
" ldflags = []"\
" }"
GN_CONTENTS += " ldflags += ["
-for (flag, QMAKE_LFLAGS): GN_CONTENTS += " \"$$flag\","
+for (flag, QMAKE_LFLAGS): GN_CONTENTS += " \"$$filter_flag_values($$flag)\","
for (flag, GN_FLAGS): GN_CONTENTS += " \"$$flag\","
-!isEmpty(QMAKE_RPATHDIR): GN_CONTENTS += " \"-Wl,-rpath=$${QMAKE_RPATHDIR}\","
+!isEmpty(QMAKE_RPATHDIR) {
+ macos: GN_CONTENTS += " \"-Wl,-rpath,$${QMAKE_RPATHDIR}\","
+ else:unix: GN_CONTENTS += " \"-Wl,-rpath=$${QMAKE_RPATHDIR}\","
+}
!isEmpty(QMAKE_RPATHLINKDIR): GN_CONTENTS += " \"-Wl,-rpath-link=$${QMAKE_RPATHLINKDIR}\","
GN_CONTENTS += " ]"