diff options
-rw-r--r-- | configure.pri | 18 | ||||
-rw-r--r-- | mkspecs/features/functions.prf | 4 | ||||
-rw-r--r-- | src/core/browser_main_parts_qt.cpp | 9 | ||||
-rw-r--r-- | src/core/config/linux.pri | 13 | ||||
-rw-r--r-- | src/core/configure.json | 15 | ||||
-rw-r--r-- | src/core/content_utility_client_qt.cpp | 23 | ||||
-rw-r--r-- | src/core/content_utility_client_qt.h | 15 | ||||
-rw-r--r-- | src/core/net/url_request_custom_job.cpp | 1 | ||||
-rw-r--r-- | src/core/render_widget_host_view_qt.cpp | 20 | ||||
-rw-r--r-- | src/core/render_widget_host_view_qt.h | 1 | ||||
-rw-r--r-- | src/webengine/doc/src/qtwebengine-features.qdoc | 18 | ||||
-rw-r--r-- | tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp | 42 |
12 files changed, 150 insertions, 29 deletions
diff --git a/configure.pri b/configure.pri index 254755743..26c57ce61 100644 --- a/configure.pri +++ b/configure.pri @@ -294,3 +294,21 @@ defineTest(qtConfTest_isWindowsHostCompiler64) { qtLog("Required 64-bit cross-building or native toolchain was not detected.") return(false) } + +# Fixme QTBUG-71772 +defineTest(qtConfTest_hasThumbFlag) { + FLAG = $$extractCFlag("-mthumb") + !isEmpty(FLAG): return(true) + FLAG = $$extractCFlag("-marm") + !isEmpty(FLAG): return(false) + + MARCH = $$extractCFlag("-march=.*") + MARMV = $$replace(MARCH, "armv",) + !isEmpty(MARMV) { + MARMV = $$split(MARMV,) + MARMV = $$member(MARMV, 0) + } + if (isEmpty(MARMV) | lessThan(MARMV, 7)): return(false) + # no flag assume mthumb + return(true) +} diff --git a/mkspecs/features/functions.prf b/mkspecs/features/functions.prf index c9bd65b03..f433de3b2 100644 --- a/mkspecs/features/functions.prf +++ b/mkspecs/features/functions.prf @@ -14,7 +14,9 @@ defineReplace(extractCFlag) { CFLAGS = $$QMAKE_CC $$QMAKE_CFLAGS OPTION = $$find(CFLAGS, $$1) OPTION = $$split(OPTION, =) - return ($$member(OPTION, 1)) + PARAM = $$member(OPTION, 1) + !isEmpty(PARAM): return ($$PARAM) + return ($$OPTION) } defineReplace(which) { diff --git a/src/core/browser_main_parts_qt.cpp b/src/core/browser_main_parts_qt.cpp index 1cb1ae5a2..273e7b45f 100644 --- a/src/core/browser_main_parts_qt.cpp +++ b/src/core/browser_main_parts_qt.cpp @@ -66,6 +66,10 @@ #include <QOpenGLContext> #endif +#if defined(OS_MACOSX) +#include "ui/base/idle/idle.h" +#endif + #if defined(Q_OS_WIN) #include "ui/display/win/screen_win.h" #else @@ -261,6 +265,11 @@ void BrowserMainPartsQt::PostMainMessageLoopRun() int BrowserMainPartsQt::PreCreateThreads() { base::ThreadRestrictions::SetIOAllowed(true); + +#if defined(OS_MACOSX) + ui::InitIdleMonitor(); +#endif + // Like ChromeBrowserMainExtraPartsViews::PreCreateThreads does. #if defined(Q_OS_WIN) display::Screen::SetScreenInstance(new display::win::ScreenWin); diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri index ed7745b89..752d2281f 100644 --- a/src/core/config/linux.pri +++ b/src/core/config/linux.pri @@ -69,6 +69,7 @@ contains(QT_ARCH, "arm") { gn_args += arm_version=$$MARMV } + # TODO: use neon detection from qtbase !lessThan(MARMV, 8) { gn_args += arm_use_neon=true } else { @@ -83,8 +84,16 @@ contains(QT_ARCH, "arm") { } } - if(isEmpty(MARMV)|lessThan(MARMV, 7)):contains(QMAKE_CFLAGS, "-marm"): gn_args += arm_use_thumb=false - else: contains(QMAKE_CFLAGS, "-mthumb"): gn_args += arm_use_thumb=true + qtConfig(webengine-arm-thumb) { + gn_args += arm_use_thumb=true # this adds -mthumb + } else { + gn_args += arm_use_thumb=false + !qtConfig(webengine-system-ffmpeg) { + # Fixme QTBUG-71772 + gn_args += media_use_ffmpeg=false + gn_args += use_webaudio_ffmpeg=false + } + } } contains(QT_ARCH, "mips") { diff --git a/src/core/configure.json b/src/core/configure.json index 3aba2d55a..e17605302 100644 --- a/src/core/configure.json +++ b/src/core/configure.json @@ -328,6 +328,10 @@ "webengine-win-compiler64": { "label": "64bit compiler", "type": "isWindowsHostCompiler64" + }, + "webengine-arm-thumb" : { + "label": "thumb instruction set", + "type": "hasThumbFlag" } }, @@ -658,7 +662,11 @@ "webengine-win-compiler64": { "label": "64bit compiler", "condition": "config.win32 && tests.webengine-win-compiler64", - "type": "isWindowsHostCompiler64", + "output": [ "privateFeature" ] + }, + "webengine-arm-thumb": { + "label": "Thumb instruction set", + "condition": "config.linux && features.webengine-embedded-build && arch.arm && tests.webengine-arm-thumb", "output": [ "privateFeature" ] } }, @@ -698,6 +706,11 @@ "type": "warning", "condition": "config.win32 && !features.webengine-win-compiler64", "message": "64-bit cross-building or native toolchain is required to build QtWebEngine." + }, + { + "type": "warning", + "condition": "config.linux && features.webengine-embedded-build && !features.webengine-system-ffmpeg && arch.arm && !features.webengine-arm-thumb", + "message": "Thumb instruction set is required to build ffmpeg for QtWebEngine." } ], diff --git a/src/core/content_utility_client_qt.cpp b/src/core/content_utility_client_qt.cpp index 9e86826fe..f49fa6386 100644 --- a/src/core/content_utility_client_qt.cpp +++ b/src/core/content_utility_client_qt.cpp @@ -42,19 +42,20 @@ #include "content/public/utility/utility_thread.h" #include "services/proxy_resolver/proxy_resolver_service.h" -ContentUtilityClientQt::ContentUtilityClientQt() { +namespace QtWebEngineCore { + +ContentUtilityClientQt::ContentUtilityClientQt() +{ } ContentUtilityClientQt::~ContentUtilityClientQt() = default; - -void ContentUtilityClientQt::RegisterServices( - ContentUtilityClient::StaticServiceMap* services) { - service_manager::EmbeddedServiceInfo proxy_resolver_info; - proxy_resolver_info.task_runner = - content::ChildThread::Get()->GetIOTaskRunner(); - proxy_resolver_info.factory = - base::Bind(&proxy_resolver::ProxyResolverService::CreateService); - services->emplace(proxy_resolver::mojom::kProxyResolverServiceName, - proxy_resolver_info); +void ContentUtilityClientQt::RegisterServices(ContentUtilityClient::StaticServiceMap *services) +{ + service_manager::EmbeddedServiceInfo proxy_resolver_info; + proxy_resolver_info.task_runner = content::ChildThread::Get()->GetIOTaskRunner(); + proxy_resolver_info.factory = base::BindRepeating(&proxy_resolver::ProxyResolverService::CreateService); + services->emplace(proxy_resolver::mojom::kProxyResolverServiceName, proxy_resolver_info); } + +} // namespace diff --git a/src/core/content_utility_client_qt.h b/src/core/content_utility_client_qt.h index df1eb5557..3fb7c97d5 100644 --- a/src/core/content_utility_client_qt.h +++ b/src/core/content_utility_client_qt.h @@ -39,18 +39,23 @@ #ifndef CONTENT_UTILITY_CLIENT_QT_H #define CONTENT_UTILITY_CLIENT_QT_H + #include "content/public/utility/content_utility_client.h" class MashServiceFactory; class UtilityMessageHandler; +namespace QtWebEngineCore { + class ContentUtilityClientQt : public content::ContentUtilityClient { - public: - ContentUtilityClientQt(); - ~ContentUtilityClientQt() override; +public: + ContentUtilityClientQt(); + ~ContentUtilityClientQt() override; - // content::ContentUtilityClient: - void RegisterServices(StaticServiceMap* services) override; + // content::ContentUtilityClient: + void RegisterServices(StaticServiceMap *services) override; }; +} // namespace + #endif diff --git a/src/core/net/url_request_custom_job.cpp b/src/core/net/url_request_custom_job.cpp index ecfa8e17a..d371c7bff 100644 --- a/src/core/net/url_request_custom_job.cpp +++ b/src/core/net/url_request_custom_job.cpp @@ -84,6 +84,7 @@ void URLRequestCustomJob::Start() void URLRequestCustomJob::Kill() { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + m_proxy->m_job = nullptr; if (m_device && m_device->isOpen()) m_device->close(); if (m_pendingReadBuffer) { diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 31a145b44..fc42d5bde 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -54,6 +54,7 @@ #include "content/browser/frame_host/frame_tree.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/common/content_switches_internal.h" +#include "content/browser/renderer_host/render_widget_host_input_event_router.h" #include "content/common/cursors/webcursor.h" #include "content/common/input_messages.h" #include "third_party/skia/include/core/SkColor.h" @@ -274,6 +275,9 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget , m_wheelAckPending(false) , m_pendingResize(false) , m_mouseWheelPhaseHandler(this) + // This frame-sink id is based on what RenderWidgetHostViewChildFrame does: + , m_frameSinkId(base::checked_cast<uint32_t>(widget->GetProcess()->GetID()), + base::checked_cast<uint32_t>(widget->GetRoutingID())) { host()->SetView(this); #ifndef QT_NO_ACCESSIBILITY @@ -291,6 +295,9 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget m_imeHasHiddenTextCapability = context && context->hasCapability(QPlatformInputContext::HiddenTextCapability); m_localSurfaceId = m_localSurfaceIdAllocator.GenerateId(); + + if (host()->delegate() && host()->delegate()->GetInputEventRouter()) + host()->delegate()->GetInputEventRouter()->AddFrameSinkIdOwner(GetFrameSinkId(), this); } RenderWidgetHostViewQt::~RenderWidgetHostViewQt() @@ -1310,14 +1317,9 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev) 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); - } + int replacementStart = ev->replacementStart() < 0 ? m_cursorPosition + ev->replacementStart() : ev->replacementStart(); + if (replacementStart >= 0 && replacementStart < m_surroundingText.length()) + replacementRange = gfx::Range(replacementStart, replacementStart + replacementLength); } // There are so-far two known cases, when an empty QInputMethodEvent is received. @@ -1683,7 +1685,7 @@ viz::SurfaceId RenderWidgetHostViewQt::GetCurrentSurfaceId() const const viz::FrameSinkId &RenderWidgetHostViewQt::GetFrameSinkId() const { - return viz::FrameSinkIdAllocator::InvalidFrameSinkId(); + return m_frameSinkId; } const viz::LocalSurfaceId &RenderWidgetHostViewQt::GetLocalSurfaceId() const diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h index 6dd4d57e5..a12ffe636 100644 --- a/src/core/render_widget_host_view_qt.h +++ b/src/core/render_widget_host_view_qt.h @@ -268,6 +268,7 @@ private: bool m_pendingResize; QList<blink::WebMouseWheelEvent> m_pendingWheelEvents; content::MouseWheelPhaseHandler m_mouseWheelPhaseHandler; + viz::FrameSinkId m_frameSinkId; uint32_t m_latestCaptureSequenceNumber = 0u; std::string m_editCommand; diff --git a/src/webengine/doc/src/qtwebengine-features.qdoc b/src/webengine/doc/src/qtwebengine-features.qdoc index 41d0581e5..1dce17e08 100644 --- a/src/webengine/doc/src/qtwebengine-features.qdoc +++ b/src/webengine/doc/src/qtwebengine-features.qdoc @@ -36,6 +36,7 @@ \list \li \l{Audio and Video Codecs} \li \l{Chromium DevTools} + \li \l{Client Certificates} \li \l{Drag and Drop} \li \l{Fullscreen} \li \l{HTML5 DRM} @@ -111,6 +112,23 @@ For more information, see \l {Qt WebEngine Debugging and Profiling}. + \section1 Client Certificates + + Some web servers, in particular many intranet sites, require the client to + authenticate itself with a certificate, called a \e {client certificate}. Qt WebEngine + will read the client certificates installed in the system settings in macOS and + Windows, and on Linux those installed into the NSS database. Certificates can + be installed into the NSS database using the \c pk12util tool. + + By default, QtWebEngine will not offer any client certificates to servers, as doing + so uniquely identifies the user and might violate privacy expectations. + + To activate support for client certificates, an application needs to listen to + the QWebEnginePage::selectClientCertificate signal and select one of the offered + certificates. For applications that can navigate to untrusted web sites, it is + recommended to always give the user a choice before uniquely identifying them + to a remote server. + \section1 Custom Schemes Qt WebEngine makes it possible for the application to define its own custom diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index a0f8f11d2..a6487d19a 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -2292,6 +2292,48 @@ void tst_QWebEngineView::imeComposition() QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 15); QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString("")); QCOMPARE(selectionChangedSpy.count(), 2); + selectionChangedSpy.clear(); + + + // 5. Mimic behavior of QtVirtualKeyboard with enabled text prediction. + evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value='QtWebEngine';"); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), QString("QtWebEngine")); + + // Move cursor into position. + QTest::keyClick(view.focusProxy(), Qt::Key_Home); + for (int j = 0; j < 2; ++j) + QTest::keyClick(view.focusProxy(), Qt::Key_Right); + QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 2); + + // Turn text into composition by using negative start position. + { + int replaceFrom = -1 * view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(); + int replaceLength = view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString().size(); + + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent event("QtWebEngine", attributes); + event.setCommitString(QString(), replaceFrom, replaceLength); + QApplication::sendEvent(view.focusProxy(), &event); + } + QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("")); + QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 11); + QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 11); + QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString("")); + QCOMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), QString("QtWebEngine")); + + // Commit. + { + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent event(QString(), attributes); + event.setCommitString("QtWebEngine", 0, 0); + QApplication::sendEvent(view.focusProxy(), &event); + } + QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngine")); + QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 11); + QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 11); + QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString("")); + QCOMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), QString("QtWebEngine")); + QCOMPARE(selectionChangedSpy.count(), 0); } void tst_QWebEngineView::newlineInTextarea() |