diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2016-06-13 10:16:32 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2016-06-14 10:43:10 +0200 |
commit | 939d104cc5a8208a0bef94ca14889ccd584a3526 (patch) | |
tree | 4d89c122ad5014a32cd8d4fbad6b7418944d2fb6 /src | |
parent | 5a7063154520544fe19bb57af3609afef898bffb (diff) | |
parent | 6c2a111f8c82b56388abf409a61a3e0d56a52156 (diff) |
Merge branch '5.7' into dev
Change-Id: I1ecb615b8df1303c27b6609970502920123b3610
Diffstat (limited to 'src')
36 files changed, 1107 insertions, 143 deletions
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro index 19b67876c..a9f5adaba 100644 --- a/src/core/api/core_api.pro +++ b/src/core/api/core_api.pro @@ -15,6 +15,7 @@ CONFIG -= create_prl # Copy this logic from qt_module.prf so that the intermediate library can be # created to the same rules as the final module linking in core_module.pro. !host_build:if(win32|mac):!macx-xcode { + contains(QT_CONFIG, simulator_and_device): CONFIG += iphonesimulator_and_iphoneos contains(QT_CONFIG, debug_and_release):CONFIG += debug_and_release contains(QT_CONFIG, build_all):CONFIG += build_all } diff --git a/src/core/browser_context_qt.h b/src/core/browser_context_qt.h index 68e1244e1..13f7220bd 100644 --- a/src/core/browser_context_qt.h +++ b/src/core/browser_context_qt.h @@ -97,7 +97,7 @@ public: BrowserContextAdapter *adapter() { return m_adapter; } #if defined(ENABLE_SPELLCHECK) - void failedToLoadDictionary(const std::string& language) override; + void failedToLoadDictionary(const std::string& language); void setSpellCheckLanguage(const QString &language); QString spellCheckLanguage() const; void setSpellCheckEnabled(bool enabled); diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp index bd62f4872..712ff5703 100644 --- a/src/core/clipboard_qt.cpp +++ b/src/core/clipboard_qt.cpp @@ -56,6 +56,13 @@ namespace QtWebEngineCore { +static void registerMetaTypes() +{ + qRegisterMetaType<QClipboard::Mode>("QClipboard::Mode"); +} + +Q_CONSTRUCTOR_FUNCTION(registerMetaTypes) + Q_GLOBAL_STATIC(ClipboardChangeObserver, clipboardChangeObserver) ClipboardChangeObserver::ClipboardChangeObserver() diff --git a/src/core/config/desktop_linux.pri b/src/core/config/desktop_linux.pri index a78082581..de0fbbc6b 100644 --- a/src/core/config/desktop_linux.pri +++ b/src/core/config/desktop_linux.pri @@ -6,5 +6,9 @@ GYP_CONFIG += \ desktop_linux=1 \ enable_widevine=1 -linux-clang: GYP_CONFIG += clang=1 host_clang=1 clang_use_chrome_plugins=0 make_clang_dir=/usr -else: GYP_CONFIG += clang=0 host_clang=0 +clang { + GYP_CONFIG += clang=1 host_clang=1 clang_use_chrome_plugins=0 make_clang_dir=/usr + linux-clang-libc++: GYP_CONFIG += use_system_libcxx=1 +} else { + GYP_CONFIG += clang=0 host_clang=0 +} diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp index 158bb0895..49c018b23 100644 --- a/src/core/content_client_qt.cpp +++ b/src/core/content_client_qt.cpp @@ -57,6 +57,18 @@ #include <QLibraryInfo> #include <QString> +#if defined(Q_OS_WIN) +#include <shlobj.h> +static QString getLocalAppDataDir() +{ + QString result; + wchar_t path[MAX_PATH]; + if (SHGetSpecialFolderPath(0, path, CSIDL_LOCAL_APPDATA, FALSE)) + result = QDir::fromNativeSeparators(QString::fromWCharArray(path)); + return result; +} +#endif + #if defined(ENABLE_PLUGINS) // The plugin logic is based on chrome/common/chrome_content_client.cc: @@ -199,10 +211,24 @@ void AddPepperWidevine(std::vector<content::PepperPluginInfo>* plugins) pluginPaths << potentialWidevinePluginPath; } } +#elif defined(Q_OS_WIN) + QDir potentialWidevineDir(getLocalAppDataDir() + "/Google/Chrome/User Data/WidevineCDM"); + if (potentialWidevineDir.exists()) { + QFileInfoList widevineVersionDirs = potentialWidevineDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed); + for (int i = 0; i < widevineVersionDirs.size(); ++i) { + QString versionDirPath(widevineVersionDirs.at(i).absoluteFilePath()); +#ifdef WIN64 + QString potentialWidevinePluginPath = versionDirPath + "/_platform_specific/win_x64/" + QString::fromLatin1(kWidevineCdmAdapterFileName); +#else + QString potentialWidevinePluginPath = versionDirPath + "/_platform_specific/win_x86/" + QString::fromLatin1(kWidevineCdmAdapterFileName); #endif -#if defined(Q_OS_LINUX) + pluginPaths << potentialWidevinePluginPath; + } + } +#elif defined(Q_OS_LINUX) pluginPaths << QStringLiteral("/opt/google/chrome/libwidevinecdmadapter.so") // Google Chrome - << QStringLiteral("/usr/lib/chromium/libwidevinecdmadapter.so"); // Arch + << QStringLiteral("/usr/lib/chromium/libwidevinecdmadapter.so") // Arch + << QStringLiteral("/usr/lib64/chromium/libwidevinecdmadapter.so"); // OpenSUSE style #endif } diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro index 3e6a9eac0..cdff4ed64 100644 --- a/src/core/core_gyp_generator.pro +++ b/src/core/core_gyp_generator.pro @@ -73,6 +73,7 @@ SOURCES = \ render_widget_host_view_qt.cpp \ renderer/content_renderer_client_qt.cpp \ renderer/pepper/pepper_flash_browser_host_qt.cpp \ + renderer/pepper/pepper_flash_clipboard_message_filter_qt.cpp \ renderer/pepper/pepper_flash_renderer_host_qt.cpp \ renderer/pepper/pepper_host_factory_qt.cpp \ renderer/pepper/pepper_isolated_file_system_message_filter.cpp \ @@ -155,6 +156,7 @@ HEADERS = \ render_widget_host_view_qt_delegate.h \ renderer/content_renderer_client_qt.h \ renderer/pepper/pepper_flash_browser_host_qt.h \ + renderer/pepper/pepper_flash_clipboard_message_filter_qt.h \ renderer/pepper/pepper_flash_renderer_host_qt.h \ renderer/pepper/pepper_host_factory_qt.h \ renderer/pepper/pepper_isolated_file_system_message_filter.h \ diff --git a/src/core/core_module.pro b/src/core/core_module.pro index fa402cc63..702b92441 100644 --- a/src/core/core_module.pro +++ b/src/core/core_module.pro @@ -14,6 +14,8 @@ load(qt_module) api_library_name = qtwebenginecoreapi$$qtPlatformTargetSuffix() api_library_path = $$OUT_PWD/api/$$getConfigDir() +# Do not precompile any headers. We are only interested in the linker step. +PRECOMPILED_HEADER = LIBS_PRIVATE += -L$$api_library_path CONFIG *= no_smart_library_merge diff --git a/src/core/gl_surface_qt.cpp b/src/core/gl_surface_qt.cpp index ef5b1d172..3982b9bd1 100644 --- a/src/core/gl_surface_qt.cpp +++ b/src/core/gl_surface_qt.cpp @@ -87,6 +87,7 @@ void* g_display; const char* g_extensions = NULL; +bool g_egl_surfaceless_context_supported = false; } // namespace @@ -109,6 +110,26 @@ private: DISALLOW_COPY_AND_ASSIGN(GLSurfaceQtEGL); }; +// The following comment is cited from chromium/ui/gl/gl_surface_egl.cc: +// SurfacelessEGL is used as Offscreen surface when platform supports +// KHR_surfaceless_context and GL_OES_surfaceless_context. This would avoid the +// need to create a dummy EGLsurface in case we render to client API targets. +class GLSurfacelessQtEGL : public GLSurfaceQt { +public: + explicit GLSurfacelessQtEGL(const gfx::Size& size); + + public: + bool Initialize() Q_DECL_OVERRIDE; + void Destroy() Q_DECL_OVERRIDE; + bool IsSurfaceless() const Q_DECL_OVERRIDE; + bool Resize(const gfx::Size& size, float scale_factor, bool has_alpha) Q_DECL_OVERRIDE; + EGLSurface GetHandle() Q_DECL_OVERRIDE; + void* GetShareHandle() Q_DECL_OVERRIDE; + +private: + DISALLOW_COPY_AND_ASSIGN(GLSurfacelessQtEGL); +}; + GLSurfaceQt::~GLSurfaceQt() { @@ -342,6 +363,23 @@ bool GLSurfaceQtEGL::InitializeOneOff() return false; } + g_egl_surfaceless_context_supported = ExtensionsContain(g_extensions, "EGL_KHR_surfaceless_context"); + if (g_egl_surfaceless_context_supported) { + scoped_refptr<GLSurface> surface = new GLSurfacelessQtEGL(Size(1, 1)); + scoped_refptr<GLContext> context = GLContext::CreateGLContext( + NULL, surface.get(), PreferIntegratedGpu); + + if (!context->MakeCurrent(surface.get())) + g_egl_surfaceless_context_supported = false; + + // Ensure context supports GL_OES_surfaceless_context. + if (g_egl_surfaceless_context_supported) { + g_egl_surfaceless_context_supported = context->HasExtension( + "GL_OES_surfaceless_context"); + context->ReleaseCurrent(surface.get()); + } + } + initialized = true; return true; } @@ -426,7 +464,7 @@ bool GLSurfaceQtEGL::Initialize() g_config, pbuffer_attributes); if (!m_surfaceBuffer) { - LOG(ERROR) << "eglCreatePbufferSurface failed with error ", GetLastEGLErrorString(); + LOG(ERROR) << "eglCreatePbufferSurface failed with error " << GetLastEGLErrorString(); Destroy(); return false; } @@ -502,6 +540,41 @@ void* GLSurfaceQt::GetConfig() return g_config; } +GLSurfacelessQtEGL::GLSurfacelessQtEGL(const gfx::Size& size) + : GLSurfaceQt(size) +{ +} + +bool GLSurfacelessQtEGL::Initialize() +{ + return true; +} + +void GLSurfacelessQtEGL::Destroy() +{ +} + +bool GLSurfacelessQtEGL::IsSurfaceless() const +{ + return true; +} + +bool GLSurfacelessQtEGL::Resize(const gfx::Size& size, float scale_factor, bool has_alpha) +{ + m_size = size; + return true; +} + +EGLSurface GLSurfacelessQtEGL::GetHandle() +{ + return EGL_NO_SURFACE; +} + +void* GLSurfacelessQtEGL::GetShareHandle() +{ + return NULL; +} + // static scoped_refptr<GLSurface> GLSurface::CreateOffscreenGLSurface(const gfx::Size& size) @@ -525,7 +598,12 @@ GLSurface::CreateOffscreenGLSurface(const gfx::Size& size) #endif } case kGLImplementationEGLGLES2: { - scoped_refptr<GLSurface> surface = new GLSurfaceQtEGL(size); + scoped_refptr<GLSurface> surface; + if (g_egl_surfaceless_context_supported) + surface = new GLSurfacelessQtEGL(size); + else + surface = new GLSurfaceQtEGL(size); + if (!surface->Initialize()) return NULL; return surface; diff --git a/src/core/gyp_run.pro b/src/core/gyp_run.pro index 2e2422dce..35b85b4c7 100644 --- a/src/core/gyp_run.pro +++ b/src/core/gyp_run.pro @@ -34,6 +34,7 @@ force_debug_info { # Copy this logic from qt_module.prf so that ninja can run according # to the same rules as the final module linking in core_module.pro. !host_build:if(win32|mac):!macx-xcode { + contains(QT_CONFIG, simulator_and_device): CONFIG += iphonesimulator_and_iphoneos contains(QT_CONFIG, debug_and_release):CONFIG += debug_and_release contains(QT_CONFIG, build_all):CONFIG += build_all } @@ -81,6 +82,7 @@ contains(QT_ARCH, "arm") { else: GYP_CONFIG += arm_fpu=\"$$MFPU\" arm_neon=0 arm_neon_optional=0 } + contains(QMAKE_CFLAGS, "-marm"): GYP_CONFIG += arm_thumb=0 contains(QMAKE_CFLAGS, "-mthumb"): GYP_CONFIG += arm_thumb=1 } diff --git a/src/core/location_provider_qt.cpp b/src/core/location_provider_qt.cpp index cc87d8417..c07bd4b0c 100644 --- a/src/core/location_provider_qt.cpp +++ b/src/core/location_provider_qt.cpp @@ -44,11 +44,13 @@ #include "type_conversion.h" #include <QtCore/QCoreApplication> +#include <QtCore/QMetaObject> #include <QtCore/QThread> #include <QtPositioning/QGeoPositionInfoSource> -#include "base/message_loop/message_loop.h" #include "base/bind.h" +#include "base/memory/weak_ptr.h" +#include "base/message_loop/message_loop.h" #include "content/browser/geolocation/geolocation_provider_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/geolocation_provider.h" @@ -63,9 +65,9 @@ public: QtPositioningHelper(LocationProviderQt *provider); ~QtPositioningHelper(); - void start(bool highAccuracy); - void stop(); - void refresh(); + Q_INVOKABLE void start(bool highAccuracy); + Q_INVOKABLE void stop(); + Q_INVOKABLE void refresh(); private Q_SLOTS: void updatePosition(const QGeoPositionInfo &); @@ -75,6 +77,7 @@ private Q_SLOTS: private: LocationProviderQt *m_locationProvider; QGeoPositionInfoSource *m_positionInfoSource; + base::WeakPtrFactory<LocationProviderQt> m_locationProviderFactory; void postToLocationProvider(const base::Closure &task); friend class LocationProviderQt; @@ -83,14 +86,13 @@ private: QtPositioningHelper::QtPositioningHelper(LocationProviderQt *provider) : m_locationProvider(provider) , m_positionInfoSource(0) + , m_locationProviderFactory(provider) { Q_ASSERT(provider); } QtPositioningHelper::~QtPositioningHelper() { - if (m_locationProvider) - m_locationProvider->m_positioningHelper = 0; } static bool isHighAccuracySource(const QGeoPositionInfoSource *source) @@ -186,7 +188,8 @@ void QtPositioningHelper::updatePosition(const QGeoPositionInfo &pos) newPos.speed = pos.hasAttribute(QGeoPositionInfo::GroundSpeed) ? pos.attribute(QGeoPositionInfo::GroundSpeed) : -1; newPos.heading = pos.hasAttribute(QGeoPositionInfo::Direction) ? pos.attribute(QGeoPositionInfo::Direction) : -1; - postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, base::Unretained(m_locationProvider), newPos)); + if (m_locationProvider) + postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, m_locationProviderFactory.GetWeakPtr(), newPos)); } void QtPositioningHelper::error(QGeoPositionInfoSource::Error positioningError) @@ -203,7 +206,8 @@ void QtPositioningHelper::error(QGeoPositionInfoSource::Error positioningError) newPos.error_code = content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; break; } - postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, base::Unretained(m_locationProvider), newPos)); + if (m_locationProvider) + postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, m_locationProviderFactory.GetWeakPtr(), newPos)); } void QtPositioningHelper::timeout() @@ -213,7 +217,8 @@ void QtPositioningHelper::timeout() // argument used in JS never comes all the way to the browser process. // Let's just treat it like any other error where the position is unavailable. newPos.error_code = content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; - postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, base::Unretained(m_locationProvider), newPos)); + if (m_locationProvider) + postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, m_locationProviderFactory.GetWeakPtr(), newPos)); } inline void QtPositioningHelper::postToLocationProvider(const base::Closure &task) @@ -230,6 +235,7 @@ LocationProviderQt::~LocationProviderQt() { if (m_positioningHelper) { m_positioningHelper->m_locationProvider = 0; + m_positioningHelper->m_locationProviderFactory.InvalidateWeakPtrs(); m_positioningHelper->deleteLater(); } } @@ -241,23 +247,21 @@ bool LocationProviderQt::StartProvider(bool highAccuracy) m_positioningHelper = new QtPositioningHelper(this); m_positioningHelper->moveToThread(guiThread); } - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(&QtPositioningHelper::start - , base::Unretained(m_positioningHelper), highAccuracy)); + + QMetaObject::invokeMethod(m_positioningHelper, "start", Qt::QueuedConnection, Q_ARG(bool, highAccuracy)); return true; } void LocationProviderQt::StopProvider() { if (m_positioningHelper) - BrowserThread::PostTask(BrowserThread::UI,FROM_HERE, base::Bind(&QtPositioningHelper::stop - , base::Unretained(m_positioningHelper))); + QMetaObject::invokeMethod(m_positioningHelper, "stop", Qt::QueuedConnection); } void LocationProviderQt::RequestRefresh() { if (m_positioningHelper) - BrowserThread::PostTask(BrowserThread::UI,FROM_HERE, base::Bind(&QtPositioningHelper::refresh - , base::Unretained(m_positioningHelper))); + QMetaObject::invokeMethod(m_positioningHelper, "refresh", Qt::QueuedConnection); } void LocationProviderQt::OnPermissionGranted() diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 34782b8c2..d6f88f74f 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -830,12 +830,12 @@ void RenderWidgetHostViewQt::sendDelegatedFrameAck() void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEvent) { - if (!m_gestureProvider.OnTouchEvent(motionEvent).succeeded) + auto result = m_gestureProvider.OnTouchEvent(motionEvent); + if (!result.succeeded) return; - bool causesScrollingIfUncancelled = true; blink::WebTouchEvent touchEvent = ui::CreateWebTouchEventFromMotionEvent(motionEvent, - causesScrollingIfUncancelled); + result.moved_beyond_slop_region); m_host->ForwardTouchEventWithLatencyInfo(touchEvent, CreateLatencyInfo(touchEvent)); } diff --git a/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.cpp b/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.cpp new file mode 100644 index 000000000..3202548ae --- /dev/null +++ b/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.cpp @@ -0,0 +1,401 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// based on chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "pepper_flash_clipboard_message_filter_qt.h" + +#include "base/pickle.h" +#include "base/strings/utf_string_conversions.h" +#include "content/public/browser/browser_thread.h" +#include "ipc/ipc_message.h" +#include "ipc/ipc_message_macros.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/private/ppb_flash_clipboard.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/resource_message_params.h" +#include "ui/base/clipboard/scoped_clipboard_writer.h" + +using content::BrowserThread; + +namespace QtWebEngineCore { + +namespace { + +const size_t kMaxClipboardWriteSize = 1000000; + +ui::ClipboardType ConvertClipboardType(uint32_t type) +{ + switch (type) { + case PP_FLASH_CLIPBOARD_TYPE_STANDARD: + return ui::CLIPBOARD_TYPE_COPY_PASTE; + case PP_FLASH_CLIPBOARD_TYPE_SELECTION: + return ui::CLIPBOARD_TYPE_SELECTION; + } + NOTREACHED(); + return ui::CLIPBOARD_TYPE_COPY_PASTE; +} + +// Functions to pack/unpack custom data from a pickle. See the header file for +// more detail on custom formats in Pepper. +// TODO(raymes): Currently pepper custom formats are stored in their own +// native format type. However we should be able to store them in the same way +// as "Web Custom" formats are. This would allow clipboard data to be shared +// between pepper applications and web applications. However currently web apps +// assume all data that is placed on the clipboard is UTF16 and pepper allows +// arbitrary data so this change would require some reworking of the chrome +// clipboard interface for custom data. +bool JumpToFormatInPickle(const base::string16& format, base::PickleIterator* iter) +{ + uint32_t size = 0; + if (!iter->ReadUInt32(&size)) + return false; + for (uint32_t i = 0; i < size; ++i) { + base::string16 stored_format; + if (!iter->ReadString16(&stored_format)) + return false; + if (stored_format == format) + return true; + int skip_length; + if (!iter->ReadLength(&skip_length)) + return false; + if (!iter->SkipBytes(skip_length)) + return false; + } + return false; +} + +bool IsFormatAvailableInPickle(const base::string16& format, const base::Pickle& pickle) +{ + base::PickleIterator iter(pickle); + return JumpToFormatInPickle(format, &iter); +} + +std::string ReadDataFromPickle(const base::string16& format, const base::Pickle& pickle) +{ + std::string result; + base::PickleIterator iter(pickle); + if (!JumpToFormatInPickle(format, &iter) || !iter.ReadString(&result)) + return std::string(); + return result; +} + +bool WriteDataToPickle(const std::map<base::string16, std::string>& data, base::Pickle* pickle) +{ + pickle->WriteUInt32(data.size()); + for (std::map<base::string16, std::string>::const_iterator it = data.begin(); it != data.end(); ++it) { + if (!pickle->WriteString16(it->first)) + return false; + if (!pickle->WriteString(it->second)) + return false; + } + return true; +} + +} // namespace + +PepperFlashClipboardMessageFilter::PepperFlashClipboardMessageFilter() {} + +PepperFlashClipboardMessageFilter::~PepperFlashClipboardMessageFilter() {} + +scoped_refptr<base::TaskRunner> +PepperFlashClipboardMessageFilter::OverrideTaskRunnerForMessage(const IPC::Message& msg) +{ + // Clipboard writes should always occur on the UI thread due to the + // restrictions of various platform APIs. In general, the clipboard is not + // thread-safe, so all clipboard calls should be serviced from the UI thread. + if (msg.type() == PpapiHostMsg_FlashClipboard_WriteData::ID) + return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); + + // Windows needs clipboard reads to be serviced from the IO thread because + // these are sync IPCs which can result in deadlocks with plugins if serviced + // from the UI thread. Note that Windows clipboard calls ARE thread-safe so it + // is ok for reads and writes to be serviced from different threads. +#if !defined(OS_WIN) + return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); +#else + return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); +#endif +} + +int32_t PepperFlashClipboardMessageFilter::OnResourceMessageReceived(const IPC::Message& msg, + ppapi::host::HostMessageContext* context) +{ + PPAPI_BEGIN_MESSAGE_MAP(PepperFlashClipboardMessageFilter, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_RegisterCustomFormat, + OnMsgRegisterCustomFormat) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_IsFormatAvailable, + OnMsgIsFormatAvailable) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_ReadData, + OnMsgReadData) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_WriteData, + OnMsgWriteData) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_GetSequenceNumber, + OnMsgGetSequenceNumber) + PPAPI_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperFlashClipboardMessageFilter::OnMsgRegisterCustomFormat( + ppapi::host::HostMessageContext* host_context, + const std::string& format_name) +{ + uint32_t format = m_custom_formats.RegisterFormat(format_name); + if (format == PP_FLASH_CLIPBOARD_FORMAT_INVALID) + return PP_ERROR_FAILED; + host_context->reply_msg = PpapiPluginMsg_FlashClipboard_RegisterCustomFormatReply(format); + return PP_OK; +} + +int32_t PepperFlashClipboardMessageFilter::OnMsgIsFormatAvailable( + ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type, + uint32_t format) +{ + if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) { + NOTIMPLEMENTED(); + return PP_ERROR_FAILED; + } + + ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); + ui::ClipboardType type = ConvertClipboardType(clipboard_type); + bool available = false; + switch (format) { + case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: { + bool plain = clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(), type); + bool plainw = clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(), type); + available = plain || plainw; + break; + } + case PP_FLASH_CLIPBOARD_FORMAT_HTML: + available = clipboard->IsFormatAvailable(ui::Clipboard::GetHtmlFormatType(), type); + break; + case PP_FLASH_CLIPBOARD_FORMAT_RTF: + available = clipboard->IsFormatAvailable(ui::Clipboard::GetRtfFormatType(), type); + break; + case PP_FLASH_CLIPBOARD_FORMAT_INVALID: + break; + default: + if (m_custom_formats.IsFormatRegistered(format)) { + std::string format_name = m_custom_formats.GetFormatName(format); + std::string clipboard_data; + clipboard->ReadData(ui::Clipboard::GetPepperCustomDataFormatType(), &clipboard_data); + base::Pickle pickle(clipboard_data.data(), clipboard_data.size()); + available = IsFormatAvailableInPickle(base::UTF8ToUTF16(format_name), pickle); + } + break; + } + + return available ? PP_OK : PP_ERROR_FAILED; +} + +int32_t PepperFlashClipboardMessageFilter::OnMsgReadData( + ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type, + uint32_t format) +{ + if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) { + NOTIMPLEMENTED(); + return PP_ERROR_FAILED; + } + + ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); + ui::ClipboardType type = ConvertClipboardType(clipboard_type); + std::string clipboard_string; + int32_t result = PP_ERROR_FAILED; + switch (format) { + case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: { + if (clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(), type)) { + base::string16 text; + clipboard->ReadText(type, &text); + if (!text.empty()) { + result = PP_OK; + clipboard_string = base::UTF16ToUTF8(text); + break; + } + } + // If the PlainTextW format isn't available or is empty, take the + // ASCII text format. + if (clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(), type)) { + result = PP_OK; + clipboard->ReadAsciiText(type, &clipboard_string); + } + break; + } + case PP_FLASH_CLIPBOARD_FORMAT_HTML: { + if (!clipboard->IsFormatAvailable(ui::Clipboard::GetHtmlFormatType(), type)) { + break; + } + + base::string16 html; + std::string url; + uint32_t fragment_start; + uint32_t fragment_end; + clipboard->ReadHTML(type, &html, &url, &fragment_start, &fragment_end); + result = PP_OK; + clipboard_string = base::UTF16ToUTF8(html.substr(fragment_start, fragment_end - fragment_start)); + break; + } + case PP_FLASH_CLIPBOARD_FORMAT_RTF: { + if (!clipboard->IsFormatAvailable(ui::Clipboard::GetRtfFormatType(), type)) { + break; + } + result = PP_OK; + clipboard->ReadRTF(type, &clipboard_string); + break; + } + case PP_FLASH_CLIPBOARD_FORMAT_INVALID: + break; + default: + if (m_custom_formats.IsFormatRegistered(format)) { + base::string16 format_name = + base::UTF8ToUTF16(m_custom_formats.GetFormatName(format)); + std::string clipboard_data; + clipboard->ReadData(ui::Clipboard::GetPepperCustomDataFormatType(), + &clipboard_data); + base::Pickle pickle(clipboard_data.data(), clipboard_data.size()); + if (IsFormatAvailableInPickle(format_name, pickle)) { + result = PP_OK; + clipboard_string = ReadDataFromPickle(format_name, pickle); + } + } + break; + } + + if (result == PP_OK) { + host_context->reply_msg = PpapiPluginMsg_FlashClipboard_ReadDataReply(clipboard_string); + } + return result; +} + +int32_t PepperFlashClipboardMessageFilter::OnMsgWriteData( + ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type, + const std::vector<uint32_t>& formats, + const std::vector<std::string>& data) +{ + if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) { + NOTIMPLEMENTED(); + return PP_ERROR_FAILED; + } + if (formats.size() != data.size()) + return PP_ERROR_FAILED; + + ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); + ui::ClipboardType type = ConvertClipboardType(clipboard_type); + // If no formats are passed in clear the clipboard. + if (formats.size() == 0) { + clipboard->Clear(type); + return PP_OK; + } + + ui::ScopedClipboardWriter scw(type); + std::map<base::string16, std::string> custom_data_map; + int32_t res = PP_OK; + for (uint32_t i = 0; i < formats.size(); ++i) { + if (data[i].length() > kMaxClipboardWriteSize) { + res = PP_ERROR_NOSPACE; + break; + } + + switch (formats[i]) { + case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: + scw.WriteText(base::UTF8ToUTF16(data[i])); + break; + case PP_FLASH_CLIPBOARD_FORMAT_HTML: + scw.WriteHTML(base::UTF8ToUTF16(data[i]), std::string()); + break; + case PP_FLASH_CLIPBOARD_FORMAT_RTF: + scw.WriteRTF(data[i]); + break; + case PP_FLASH_CLIPBOARD_FORMAT_INVALID: + res = PP_ERROR_BADARGUMENT; + break; + default: + if (m_custom_formats.IsFormatRegistered(formats[i])) { + std::string format_name = m_custom_formats.GetFormatName(formats[i]); + custom_data_map[base::UTF8ToUTF16(format_name)] = data[i]; + } else { + // Invalid format. + res = PP_ERROR_BADARGUMENT; + break; + } + } + + if (res != PP_OK) + break; + } + + if (custom_data_map.size() > 0) { + base::Pickle pickle; + if (WriteDataToPickle(custom_data_map, &pickle)) { + scw.WritePickledData(pickle, ui::Clipboard::GetPepperCustomDataFormatType()); + } else { + res = PP_ERROR_BADARGUMENT; + } + } + + if (res != PP_OK) { + // Need to clear the objects so nothing is written. + scw.Reset(); + } + + return res; +} + +int32_t PepperFlashClipboardMessageFilter::OnMsgGetSequenceNumber( + ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type) +{ + if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) { + NOTIMPLEMENTED(); + return PP_ERROR_FAILED; + } + + ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); + ui::ClipboardType type = ConvertClipboardType(clipboard_type); + int64_t sequence_number = clipboard->GetSequenceNumber(type); + host_context->reply_msg = PpapiPluginMsg_FlashClipboard_GetSequenceNumberReply(sequence_number); + return PP_OK; +} + +} // namespace QtWebEngineCore diff --git a/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.h b/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.h new file mode 100644 index 000000000..c00e668ea --- /dev/null +++ b/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// based on chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_QT_H +#define PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_QT_H + +#include <string> +#include <vector> + +#include "base/compiler_specific.h" +#include "ppapi/host/resource_message_filter.h" +#include "ppapi/shared_impl/flash_clipboard_format_registry.h" + +namespace ppapi { +namespace host { +struct HostMessageContext; +} +} + +namespace ui { +class ScopedClipboardWriter; +} + +namespace QtWebEngineCore { + +// Resource message filter for accessing the clipboard in Pepper. Pepper +// supports reading/writing custom formats from the clipboard. Currently, all +// custom formats that are read/written from the clipboard through pepper are +// stored in a single real clipboard format (in the same way the "web custom" +// clipboard formats are). This is done so that we don't have to have use real +// clipboard types for each custom clipboard format which may be a limited +// resource on a particular platform. +class PepperFlashClipboardMessageFilter : public ppapi::host::ResourceMessageFilter { +public: + PepperFlashClipboardMessageFilter(); + +protected: + // ppapi::host::ResourceMessageFilter overrides. + scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage(const IPC::Message& msg) override; + int32_t OnResourceMessageReceived(const IPC::Message& msg, ppapi::host::HostMessageContext* context) override; + +private: + ~PepperFlashClipboardMessageFilter() override; + + int32_t OnMsgRegisterCustomFormat(ppapi::host::HostMessageContext* host_context, const std::string& format_name); + int32_t OnMsgIsFormatAvailable(ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type, + uint32_t format); + int32_t OnMsgReadData(ppapi::host::HostMessageContext* host_context, + uint32_t clipoard_type, + uint32_t format); + int32_t OnMsgWriteData(ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type, + const std::vector<uint32_t>& formats, + const std::vector<std::string>& data); + int32_t OnMsgGetSequenceNumber(ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type); + + int32_t WriteClipboardDataItem(uint32_t format, + const std::string& data, + ui::ScopedClipboardWriter* scw); + + ppapi::FlashClipboardFormatRegistry m_custom_formats; + + DISALLOW_COPY_AND_ASSIGN(PepperFlashClipboardMessageFilter); +}; + +} // namespace QtWebEngineCore + +#endif // PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_QT_H diff --git a/src/core/renderer/pepper/pepper_host_factory_qt.cpp b/src/core/renderer/pepper/pepper_host_factory_qt.cpp index a0bab1e51..9aece100c 100644 --- a/src/core/renderer/pepper/pepper_host_factory_qt.cpp +++ b/src/core/renderer/pepper/pepper_host_factory_qt.cpp @@ -54,10 +54,10 @@ #include "ppapi/shared_impl/ppapi_permissions.h" #include "pepper_flash_browser_host_qt.h" +#include "pepper_flash_clipboard_message_filter_qt.h" #include "pepper_isolated_file_system_message_filter.h" using ppapi::host::MessageFilterHost; -using ppapi::host::ResourceHost; using ppapi::host::ResourceMessageFilter; namespace QtWebEngineCore { @@ -80,10 +80,18 @@ std::unique_ptr<ppapi::host::ResourceHost> PepperHostFactoryQt::CreateResourceHo if (!host_->IsValidInstance(instance)) return nullptr; - if (host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_FLASH) - && message.type() == PpapiHostMsg_Flash_Create::ID) - return base::WrapUnique( - new PepperFlashBrowserHostQt(host_, instance, resource)); + // Flash interfaces. + if (host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_FLASH)) { + switch (message.type()) { + case PpapiHostMsg_Flash_Create::ID: + return base::WrapUnique(new PepperFlashBrowserHostQt(host_, instance, resource)); + case PpapiHostMsg_FlashClipboard_Create::ID: { + scoped_refptr<ResourceMessageFilter> clipboard_filter(new PepperFlashClipboardMessageFilter); + return base::WrapUnique(new MessageFilterHost( + host_->GetPpapiHost(), instance, resource, clipboard_filter)); + } + } + } // Permissions for the following interfaces will be checked at the // time of the corresponding instance's methods calls (because diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 134b5b63c..15125b9d8 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -70,6 +70,7 @@ #include "content/public/browser/navigation_entry.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/favicon_status.h" +#include "content/public/common/content_constants.h" #include <content/public/common/drop_data.h> #include "content/public/common/page_state.h" #include "content/public/common/page_zoom.h" @@ -517,7 +518,12 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT urlString.append(","); urlString.append(encodedData.constData(), encodedData.length()); - content::NavigationController::LoadURLParams params((GURL(urlString))); + GURL dataUrlToLoad(urlString); + if (dataUrlToLoad.spec().size() > url::kMaxURLChars) { + d->adapterClient->loadFinished(false, baseUrl, false, net::ERR_ABORTED); + return; + } + content::NavigationController::LoadURLParams params((dataUrlToLoad)); params.load_type = content::NavigationController::LOAD_TYPE_DATA; params.base_url_for_data_url = toGurl(baseUrl); params.virtual_url_for_data_url = baseUrl.isEmpty() ? GURL(url::kAboutBlankURL) : toGurl(baseUrl); @@ -1114,10 +1120,7 @@ static blink::WebDragOperationsMask toWeb(const Qt::DropActions action) static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeData *mimeData) { - if (mimeData->hasText()) - dropData->text = toNullableString16(mimeData->text()); - if (mimeData->hasHtml()) - dropData->html = toNullableString16(mimeData->html()); + Q_ASSERT(dropData->filenames.empty()); Q_FOREACH (const QUrl &url, mimeData->urls()) { if (url.isLocalFile()) { ui::FileInfo uifi; @@ -1125,6 +1128,12 @@ static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeDat dropData->filenames.push_back(uifi); } } + if (!dropData->filenames.empty()) + return; + if (mimeData->hasHtml()) + dropData->html = toNullableString16(mimeData->html()); + else if (mimeData->hasText()) + dropData->text = toNullableString16(mimeData->text()); } void WebContentsAdapter::enterDrag(QDragEnterEvent *e, const QPoint &screenPos) diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index 80aabaa4d..c50f38b38 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -257,6 +257,7 @@ public: virtual void updateContentsSize(const QSizeF &size) = 0; virtual void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions, const QPixmap &pixmap, const QPoint &offset) = 0; + virtual bool isEnabled() const = 0; virtual QSharedPointer<BrowserContextAdapter> browserContextAdapter() = 0; virtual WebContentsAdapter* webContentsAdapter() = 0; diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp index 1d39d8af8..e487fca46 100644 --- a/src/core/web_contents_view_qt.cpp +++ b/src/core/web_contents_view_qt.cpp @@ -120,6 +120,8 @@ void WebContentsViewQt::GetContainerBounds(gfx::Rect* out) const void WebContentsViewQt::Focus() { + if (!m_client->isEnabled()) + return; if (content::RenderWidgetHostView *rwhv = m_webContents->GetRenderWidgetHostView()) rwhv->Focus(); m_client->focusContainer(); diff --git a/src/webengine/api/qquickwebenginesettings.cpp b/src/webengine/api/qquickwebenginesettings.cpp index 9096dd604..3fea83166 100644 --- a/src/webengine/api/qquickwebenginesettings.cpp +++ b/src/webengine/api/qquickwebenginesettings.cpp @@ -217,7 +217,7 @@ bool QQuickWebEngineSettings::errorPageEnabled() const Disabled by default. - \sa {Pepper Plugin API Support} + \sa {Pepper Plugin API} */ bool QQuickWebEngineSettings::pluginsEnabled() const { diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 1b1dcec25..59b5d17db 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -124,6 +124,8 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate() , m_dpiScale(1.0) , m_backgroundColor(Qt::white) , m_defaultZoomFactor(1.0) + // QTBUG-53467 + , m_menuEnabled(true) { // The gold standard for mobile web content is 160 dpi, and the devicePixelRatio expected // is the (possibly quantized) ratio of device dpi to 160 dpi. @@ -141,6 +143,8 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate() // 1x, 2x, 3x etc assets that fit an integral number of pixels. setDevicePixelRatio(qMax(1, qRound(webPixelRatio))); } + if (platform == QLatin1Literal("eglfs")) + m_menuEnabled = false; #ifndef QT_NO_ACCESSIBILITY QAccessible::installFactory(&webAccessibleFactory); #endif // QT_NO_ACCESSIBILITY @@ -191,6 +195,12 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu { Q_Q(QQuickWebEngineView); + if (!m_menuEnabled) { + qWarning("You are trying to open context menu on eglfs backend, which is not currently supported\n" + "See QTBUG-53467."); + return false; + } + // Assign the WebEngineView as the parent of the menu, so mouse events are properly propagated // on OSX. QObject *menu = ui()->addMenu(q, QString(), data.pos); @@ -1075,6 +1085,12 @@ void QQuickWebEngineViewPrivate::startDragging(const content::DropData &dropData adapter->startDragging(q_ptr->window(), dropData, allowedActions, pixmap, offset); } +bool QQuickWebEngineViewPrivate::isEnabled() const +{ + const Q_Q(QQuickWebEngineView); + return q->isEnabled(); +} + bool QQuickWebEngineView::isLoading() const { Q_D(const QQuickWebEngineView); @@ -1184,24 +1200,32 @@ void QQuickWebEngineView::setBackgroundColor(const QColor &color) The default value is false. */ -bool QQuickWebEngineView::isAudioMuted() const { +bool QQuickWebEngineView::isAudioMuted() const +{ const Q_D(QQuickWebEngineView); - return d->adapter->isAudioMuted(); - + if (d->adapter) + return d->adapter->isAudioMuted(); + return false; } -void QQuickWebEngineView::setAudioMuted(bool muted) { + +void QQuickWebEngineView::setAudioMuted(bool muted) +{ Q_D(QQuickWebEngineView); bool _isAudioMuted = isAudioMuted(); - d->adapter->setAudioMuted(muted); - if (_isAudioMuted != muted) { - Q_EMIT audioMutedChanged(muted); + if (d->adapter) { + d->adapter->setAudioMuted(muted); + if (_isAudioMuted != muted) { + Q_EMIT audioMutedChanged(muted); + } } } bool QQuickWebEngineView::recentlyAudible() const { const Q_D(QQuickWebEngineView); - return d->adapter->recentlyAudible(); + if (d->adapter) + return d->adapter->recentlyAudible(); + return false; } void QQuickWebEngineView::printToPdf(const QString& filePath, PrintedPageSizeId pageSizeId, PrintedPageOrientation orientation) diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h index d287b46ca..b72f79f30 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -54,6 +54,7 @@ #include <private/qtwebengineglobal_p.h> #include "qquickwebenginescript_p.h" #include <QQuickItem> +#include <QtGui/qcolor.h> QT_BEGIN_NAMESPACE diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 82a9e9612..909763614 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -187,6 +187,7 @@ public: virtual void updateContentsSize(const QSizeF &size) Q_DECL_OVERRIDE; void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions, const QPixmap &pixmap, const QPoint &offset) Q_DECL_OVERRIDE; + virtual bool isEnabled() const Q_DECL_OVERRIDE; virtual QSharedPointer<QtWebEngineCore::BrowserContextAdapter> browserContextAdapter() Q_DECL_OVERRIDE; QtWebEngineCore::WebContentsAdapter *webContentsAdapter() Q_DECL_OVERRIDE; @@ -233,6 +234,8 @@ private: qreal m_dpiScale; QColor m_backgroundColor; qreal m_defaultZoomFactor; + // QTBUG-53467 + bool m_menuEnabled; }; #ifndef QT_NO_ACCESSIBILITY diff --git a/src/webengine/doc/qtwebengine.qdocconf b/src/webengine/doc/qtwebengine.qdocconf index baa4a9859..009902080 100644 --- a/src/webengine/doc/qtwebengine.qdocconf +++ b/src/webengine/doc/qtwebengine.qdocconf @@ -4,8 +4,6 @@ project = QtWebEngine description = Qt WebEngine Reference Documentation version = $QT_VERSION -examplesinstallpath = qtwebengine - qhp.projects = QtWebEngine qhp.QtWebEngine.file = qtwebengine.qhp @@ -42,8 +40,10 @@ tagfile = ../../../doc/qtwebengine/qtwebengine.tags depends += qtcore \ qtgui \ + qtlocation \ qtnetwork \ qtprintsupport \ + qtpositioning \ qtqml \ qtquick \ qtquickcontrols \ diff --git a/src/webengine/doc/src/external-resources.qdoc b/src/webengine/doc/src/external-resources.qdoc index 6356e13bb..c4cfe24af 100644 --- a/src/webengine/doc/src/external-resources.qdoc +++ b/src/webengine/doc/src/external-resources.qdoc @@ -47,7 +47,47 @@ /*! \externalpage http://www.openh264.org/ - \title OpenH264 + \title OpenH264 Project Homepage +*/ + +/*! + \externalpage http://html5demos.com/drag + \title HTML5 Demos - Drag and Drop +*/ + +/*! + \externalpage http://html5demos.com/drag-anything + \title HTML5 Demos - Simple Drag and Drop +*/ + +/*! + \externalpage http://html5demos.com/dnd-upload + \title HTML5 Demos - Drag and Drop, Automatic Upload +*/ + +/*! + \externalpage http://html5demos.com/file-api + \title HTML5 Demos - File API +*/ + +/*! + \externalpage http://www.widevine.com/wv_drm.html + \title Widevine DRM +*/ + +/*! + \externalpage http://demo.castlabs.com/ + \title castLabs +*/ + +/*! + \externalpage http://ssdemo04.swankmp.net/ + \title Swank Motion Pictures, Inc. +*/ + +/*! + \externalpage https://shaka-player-demo.appspot.com/demo/ + \title Shaka Player */ /* diff --git a/src/webengine/doc/src/qtwebengine-features.qdoc b/src/webengine/doc/src/qtwebengine-features.qdoc new file mode 100644 index 000000000..52f7da928 --- /dev/null +++ b/src/webengine/doc/src/qtwebengine-features.qdoc @@ -0,0 +1,234 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtwebengine-features.html + \title Qt WebEngine Features + + \brief Summarizes Qt WebEngine features. + + Qt WebEngine supports the following Chromium features: + + \list + \li \l{Audio and Video Codecs} + \li \l{Chromium DevTools} + \li \l{Drag and Drop} + \li \l{Fullscreen} + \li \l{HTML5 DRM} + \li \l{HTML5 Geolocation} + \li \l{Pepper Plugin API} + \li \l{Print to PDF} + \li \l{WebRTC} + \endlist + + \section1 Audio and Video Codecs + + Qt WebEngine supports the MPEG-4 Part 14 (MP4) file format only if the + required proprietary audio and video codecs, such as H.264 and MPEG layer-3 + (MP3), have been enabled. Proprietary codecs can be enabled by passing the + following option to qmake when building Qt WebEngine: + + \code + qmake WEBENGINE_CONFIG+=use_proprietary_codecs + \endcode + + \warning When distributing proprietary codec libraries, you must acquire + licenses for them. + + \l FFmpeg is a cross-platform solution to record, convert, and stream audio + and video. It can be configured for use with several codecs, which rises + licensing issues during distribution with the codec libraries. For some + codecs, open source implementations, such as \l{OpenH264 Project Homepage} + {OpenH264}, are available. + + \section1 Chromium DevTools + + The Chromium DevTools provide the ability to inspect and debug layout and + performance issues of any web content. + + This feature can be tested by launching a Qt WebEngine application with the + command line option \c {--remote-debugging-port=[your-port]} or by setting + the environment variable \c QTWEBENGINE_REMOTE_DEBUGGING, and then using a + Chromium based browser (such as \l{WebEngine Demo Browser Example} + {Demo Browser} or \l{WebEngine Quick Nano Browser}{Nano Browser}) to connect + to \c {http://localhost:[your-port]}. + + For more information, see \l {Qt WebEngine Debugging and Profiling}. + + \section1 Drag and Drop + + Qt WebEngine supports HTML5 drag and drop. + + This feature can be tested by opening an HTML5 drag and drop demo, such as + \l{HTML5 Demos - Drag and Drop}, \l{HTML5 Demos - Simple Drag and Drop}, or + \l{HTML5 Demos - Drag and Drop, Automatic Upload}, in \l{WebEngine Demo + Browser Example}{Demo Browser} or \l{WebEngine Quick Nano Browser} + {Nano Browser}. + + Dragging files into the browser is not actually part of HTML5, but it is + supported. It can be tested by opening \l{HTML5 Demos - File API}. + + Support for this feature was added in Qt 5.7.0. + + \section1 Fullscreen + + Qt WebEngine supports viewing web content in fullscreen mode. For more + information, see \l{WebEngineSettings::fullscreenSupportEnabled} + {WebEngineSettings.fullscreenSupportEnabled}, + \l{WebEngineView::fullScreenRequested}{WebEngineView.fullScreenRequested}, + QWebEngineSettings::FullScreenSupportEnabled, and + QWebEnginePage::fullScreenRequested. + + This feature can be tested by playing a video from YouTube in \l{WebEngine + Demo Browser Example}{Demo Browser} or \l{WebEngine Quick Nano Browser} + {Nano Browser}, and clicking the full screen icon to go into fullscreen + mode. + + Support for this feature was added in Qt 5.6.0. + + \section1 HTML5 DRM + + Qt WebEngine supports viewing DRM protected videos if the \l{Widevine DRM} + plugin has been installed. + + The video format most commonly used by DRM services, H.264, requires + proprietary audio and video codecs. For more information about enabling the + codecs, see \l{Audio and Video Codecs}. + + This feature can be tested by playing a video in \l{WebEngine Demo Browser + Example}{Demo Browser} or \l{WebEngine Quick Nano Browser}{Nano Browser} + from \l{castLabs}, \l{Swank Motion Pictures, Inc.}, or \l{Shaka Player}. + + Support for this feature was added in Qt 5.7.0. + + \section1 HTML5 Geolocation + + Qt WebEngine supports JavaScript Geolocation API with \l {Qt Location} as a + backend. The application has to explicitly allow the feature by using + QWebEnginePage::Geolocation or \l{WebEngineView::Feature} + {WebEngineView.Feature}. + + This feature can be tested if Qt Location has been built before Qt WebEngine. + The \c http://html5demos.com/geo page can be opened in the \l{WebEngine Demo + Browser Example}{Demo Browser} and allowed to find the current position of + the user. Note that on Windows an external GPS receiver must be connected to + the application. For more information, see \l{Qt Positioning}. + + Support for this feature was added in Qt 5.5.0. + + \section1 Pepper Plugin API + + Qt WebEngine supports loading Pepper Plugin API (PPAPI) plugins if + WebEngineSettings::pluginsEnabled or QWebEngineSettings::PluginsEnabled + is set. + + Except for the Adobe Flash Player plugin, the plugins must be loaded + manually using the Chromium command line syntax with the + \c --register-pepper-plugins argument. The argument value is a list of + entries, separated by commas, that contain the file path and one or several + MIME types, separated by semicolons: + + \code + <file-path-plugin1>;<mime-type-plugin1>,<file-path-plugin2>;<mime-type1-plugin2>;<mime-type2-plugin2> + \endcode + + For example: + + \code + --register-pepper-plugins="libppapi_example.so;application/x-ppapi-example" + \endcode + + The MIME type is important because it determines which embeds the plugin is + used for. + + Support for this feature was added in Qt 5.6.0. + + \section2 Pepper Flash Player Plugin Support + + The Pepper Flash player plugin can be loaded automatically if it is + installed in one of the following locations, depending on the platform: + + \list + \li Windows + \code + C:\Windows\SysWOW64\Macromed\Flash\pepflashplayer*.dll + C:\Windows\System32\Macromed\Flash\pepflashplayer*.dll + \endcode + \li OS X + \code + /Library/Internet Plug-Ins/PepperFlashPlayer/PepperFlashPlayer.plugin + \endcode + \li Linux + \code + /usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so + /usr/lib/PepperFlash/libpepflashplayer.so + /usr/lib64/chromium/PepperFlash/libpepflashplayer.so + \endcode + \endlist + + You can also load the Pepper Flash player from a specific location by using + command line arguments: + + \code + --ppapi-flash-path=./libpepflashplayer.so + \endcode + + By default, the Flash version is set to \c{11.2.999.999}. You can use the + \c{ppapi-flash-version=} argument to set another Flash version in the + format \c{major.minor.build.revision}: + + \code + --ppapi-flash-version=16.0.0.235 + \endcode + + This feature can be tested in \l{WebEngine Demo Browser Example}{Demo Browser} + or \l{WebEngine Quick Nano Browser}{Nano Browser} if the Adobe Flash PPAPI + plugin is installed and plugins are enabled in the browser. To test the + feature, the \c https://helpx.adobe.com/flash-player.html page can be opened + in the browser. + + \section1 Print to PDF + + Qt WebEngine supports printing a web page to a PDF file. For more + information, see QWebEnginePage::printToPdf() and + \l{WebEngineView::printToPdf}{WebEngineView.printToPdf}. + + This feature can be tested in \l{WebEngine Demo Browser Example} + {Demo Browser} by selecting \uicontrol File > \uicontrol {Print to PDF}. + + Support for this feature was added in Qt 5.7.0. + + \section1 WebRTC + + WebRTC provides browsers with Real-Time Communications (RTC) capabilities + via simple APIs. For more information, see \l{WebEngineView::Feature} + {WebEngineView.Feature} and QWebEnginePage::Feature. + + This feature can be tested by setting up a webcam or microphone and then + opening \c https://test.webrtc.org/ in \l{WebEngine Widgets Simple Browser + Example}{Simple Browser} or \l{WebEngine Quick Nano Browser}{Nano Browser}. +*/ diff --git a/src/webengine/doc/src/qtwebengine-index.qdoc b/src/webengine/doc/src/qtwebengine-index.qdoc index 4cca431f0..e7314fcf9 100644 --- a/src/webengine/doc/src/qtwebengine-index.qdoc +++ b/src/webengine/doc/src/qtwebengine-index.qdoc @@ -46,6 +46,7 @@ \list \li \l{Qt WebEngine Overview} + \li \l{Qt WebEngine Features} \li \l{Qt WebEngine Platform Notes} \li \l{Qt WebEngine Licensing} \li \l{Qt WebEngine Debugging and Profiling} diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc index d4d9af199..7ae3afaf4 100644 --- a/src/webengine/doc/src/qtwebengine-overview.qdoc +++ b/src/webengine/doc/src/qtwebengine-overview.qdoc @@ -60,16 +60,16 @@ The functionality in Qt WebEngine is divided into the following modules: \list - \li \l{Qt WebEngine Widgets} for creating widget-based web applications - \li \l{Qt WebEngine} for creating Qt Quick based web applications - \li \l{Qt WebEngine Core} for interacting with Chromium + \li \l{Qt WebEngine Widgets Module} for creating widget-based web applications + \li \l{Qt WebEngine Module} for creating Qt Quick based web applications + \li \l{Qt WebEngine Core Module} for interacting with Chromium \endlist Page rendering and JavaScript execution are separated from the GUI process into the Qt WebEngine Process. It is a library that must be shipped with the application if the Qt libraries are bundled into the application. - \section2 Qt WebEngine Widgets + \section2 Qt WebEngine Widgets Module \image qtwebenginewidgets-model.png @@ -82,7 +82,7 @@ \e cookies. Profiles can be used to isolate pages from each other. A typical use case is a dedicated profile for a \e {private browsing} mode, where no information is permanently saved. - \section2 Qt WebEngine + \section2 Qt WebEngine Module \image qtwebengine-model.png @@ -90,7 +90,7 @@ except that there is no separately accessible web engine page. The supported page functionality is integrated into the web engine view. - \section2 Qt WebEngine Core + \section2 Qt WebEngine Core Module The Qt WebEngine core is based on the \l {Chromium Project}. Chromium provides its own network and painting engines and is developed tightly together with its dependent modules, and diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc index 4bb449016..ecec53bda 100644 --- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc +++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc @@ -87,6 +87,7 @@ \section2 Linux On Linux, Clang or GCC version 4.7 or later is required. + Supported configurations are \c linux-g++ and \c{linux-clang}. Qt WebEngine requires \c pkg-config to detect most of its dependencies. The following \c pkg-config files are required: @@ -118,84 +119,6 @@ \note Qt WebEngine cannot be built for the 32-bit mode of OS X (using the \c macx-clang-32 \c mkspec). - \section1 Pepper Plugin API Support - - Qt WebEngine supports loading Pepper Plugin API (PPAPI) plugins if - WebEngineSettings::pluginsEnabled or QWebEngineSettings::PluginsEnabled - is set. - - Except for the Adobe Flash Player plugin, the plugins must be loaded manually using the - Chromium command line syntax with the \c --register-pepper-plugins argument. - The argument value is a list of entries, separated by commas, that contain the file path and - one or several MIME types, separated by semicolons: - - \code - <file-path-plugin1>;<mime-type-plugin1>,<file-path-plugin2>;<mime-type1-plugin2>;<mime-type2-plugin2> - \endcode - - For example: - - \code - --register-pepper-plugins="libppapi_example.so;application/x-ppapi-example" - \endcode - - The MIME type is important because it determines which embeds the plugin is used for. - - \section2 Pepper Flash Player Plugin Support - - The Pepper Flash player plugin can be loaded automatically if it is installed in one of the - following locations, depending on the platform: - - \list - \li Windows - \code - C:\Windows\SysWOW64\Macromed\Flash\pepflashplayer*.dll - C:\Windows\System32\Macromed\Flash\pepflashplayer*.dll - \endcode - \li OS X - \code - /Library/Internet Plug-Ins/PepperFlashPlayer/PepperFlashPlayer.plugin - \endcode - \li Linux - \code - /usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so - /usr/lib/PepperFlash/libpepflashplayer.so - /usr/lib64/chromium/PepperFlash/libpepflashplayer.so - \endcode - \endlist - - You can also load the Pepper Flash player from a specific location by using command line - arguments: - - \code - --ppapi-flash-path=./libpepflashplayer.so - \endcode - - By default, the Flash version is set to \c{11.2.999.999}. You can use the - \c{ppapi-flash-version=} argument to set another Flash version in the - in the format \c{major.minor.build.revision}: - - \code - --ppapi-flash-version=16.0.0.235 - \endcode - - \section1 Audio and Video Codec Support - - Qt WebEngine supports the MPEG-4 Part 14 (MP4) file format only if the required proprietary - audio and video codecs, such as H.264 and MPEG layer-3 (MP3), have been enabled. Proprietary - codecs can be enabled by passing the following option to qmake: - - \code - qmake WEBENGINE_CONFIG+=use_proprietary_codecs - \endcode - - \warning When distributing proprietary codec libraries, you must acquire licenses for them. - - \l FFmpeg is a cross-platform solution to record, convert, and stream audio and video. It can - be configured for use with several codecs, which rises licensing issues during distribution - with the codec libraries. For some codecs, open source implementations, such as \l {OpenH264}, - are available. - \section1 Mac App Store Compatibility By default, Qt WebEngine uses private OS X API, which might cause an application to be @@ -203,7 +126,7 @@ calls, Qt WebEngine has to be recompiled: \code - qmake WEBENGINE_CONFIG += use_appstore_compliant_code + qmake WEBENGINE_CONFIG+=use_appstore_compliant_code \endcode However, this will cause some behavioral changes, such as: diff --git a/src/webengine/doc/src/webengineview.qdoc b/src/webengine/doc/src/webengineview.qdoc index a4630484e..0f83d0d23 100644 --- a/src/webengine/doc/src/webengineview.qdoc +++ b/src/webengine/doc/src/webengineview.qdoc @@ -404,7 +404,7 @@ \since QtWebEngine 1.1 Finds the specified string, \a subString, in the page. - To clear the selection, just pass an empty string. + To clear the search highlight, just pass an empty string. */ /*! @@ -412,7 +412,7 @@ \since QtWebEngine 1.1 Finds the specified string, \a subString, in the page, using the given \a options. - To clear the selection, just pass an empty string. + To clear the search highlight, just pass an empty string. \code findText("Qt", WebEngineView.FindBackward | WebEngineView.FindCaseSensitively); @@ -424,7 +424,7 @@ \since QtWebEngine 1.1 Finds the specified string, \a subString, in the page, using the given \a options. - To clear the selection, just pass an empty string. + To clear the search highlight, just pass an empty string. The \a resultCallback must take a boolean parameter. It will be called with a value of true if the \a subString was found; otherwise the callback value diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp index 9ad86800c..5e39cc2b3 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp +++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp @@ -222,18 +222,33 @@ void RenderWidgetHostViewQtDelegateQuick::focusOutEvent(QFocusEvent *event) void RenderWidgetHostViewQtDelegateQuick::mousePressEvent(QMouseEvent *event) { - if (!m_isPopup && (parentItem() && parentItem()->property("activeFocusOnPress").toBool())) + QQuickItem *parent = parentItem(); + if (!m_isPopup && (parent && parent->property("activeFocusOnPress").toBool())) forceActiveFocus(); + if (parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) { + event->ignore(); + return; + } m_client->forwardEvent(event); } void RenderWidgetHostViewQtDelegateQuick::mouseMoveEvent(QMouseEvent *event) { + QQuickItem *parent = parentItem(); + if (parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) { + event->ignore(); + return; + } m_client->forwardEvent(event); } void RenderWidgetHostViewQtDelegateQuick::mouseReleaseEvent(QMouseEvent *event) { + QQuickItem *parent = parentItem(); + if (parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) { + event->ignore(); + return; + } m_client->forwardEvent(event); } @@ -254,14 +269,24 @@ void RenderWidgetHostViewQtDelegateQuick::wheelEvent(QWheelEvent *event) void RenderWidgetHostViewQtDelegateQuick::touchEvent(QTouchEvent *event) { + QQuickItem *parent = parentItem(); if (event->type() == QEvent::TouchBegin && !m_isPopup - && (parentItem() && parentItem()->property("activeFocusOnPress").toBool())) + && (parent && parent->property("activeFocusOnPress").toBool())) forceActiveFocus(); + if (parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) { + event->ignore(); + return; + } m_client->forwardEvent(event); } void RenderWidgetHostViewQtDelegateQuick::hoverMoveEvent(QHoverEvent *event) { + QQuickItem *parent = parentItem(); + if (parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) { + event->ignore(); + return; + } m_client->forwardEvent(event); } diff --git a/src/webenginewidgets/api/qwebenginecertificateerror.cpp b/src/webenginewidgets/api/qwebenginecertificateerror.cpp index ebe3cdbec..289bb7ec0 100644 --- a/src/webenginewidgets/api/qwebenginecertificateerror.cpp +++ b/src/webenginewidgets/api/qwebenginecertificateerror.cpp @@ -85,6 +85,10 @@ QWebEngineCertificateError::~QWebEngineCertificateError() This enum describes the type of certificate error encountered. + The values of this enum type match the SSL errors Chromium provides. + QSslError::SslError values are not used directly, because the Qt error + categories cannot be mapped to the Chromium error categories. + \value SslPinnedKeyNotInCertificateChain The certificate did not match the built-in public keys pinned for the host name. \value CertificateCommonNameInvalid The certificate's common name did not match the host name. diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 0e7f02f16..3f11e5aef 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -1143,6 +1143,7 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData view->contextMenuEvent(&event); break; case Qt::CustomContextMenu: + contextData = data; Q_EMIT view->customContextMenuRequested(data.pos); break; case Qt::ActionsContextMenu: @@ -1269,9 +1270,21 @@ void QWebEnginePagePrivate::startDragging(const content::DropData &dropData, adapter->startDragging(view, dropData, allowedActions, pixmap, offset); } +bool QWebEnginePagePrivate::isEnabled() const +{ + const Q_Q(QWebEnginePage); + const QWidget *view = q->view(); + if (view) + return view->isEnabled(); + return true; +} + QMenu *QWebEnginePage::createStandardContextMenu() { Q_D(QWebEnginePage); + if (!d->contextData.d) + return nullptr; + QMenu *menu = new QMenu(d->view); QAction *action = 0; const WebEngineContextMenuData &contextMenuData = *d->contextData.d; diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h index 22bfaff95..26ef80e9a 100644 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ b/src/webenginewidgets/api/qwebenginepage_p.h @@ -135,6 +135,7 @@ public: virtual void updateContentsSize(const QSizeF &size) Q_DECL_OVERRIDE; void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions, const QPixmap &pixmap, const QPoint &offset) Q_DECL_OVERRIDE; + virtual bool isEnabled() const Q_DECL_OVERRIDE; virtual QSharedPointer<QtWebEngineCore::BrowserContextAdapter> browserContextAdapter() Q_DECL_OVERRIDE; QtWebEngineCore::WebContentsAdapter *webContentsAdapter() Q_DECL_OVERRIDE; diff --git a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc index e6236ec98..89d7cfb0c 100644 --- a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc +++ b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc @@ -248,7 +248,7 @@ \b {Qt WebEngine} \code QWebEnginePage page; - page.runJavascript("document.documentElement.contentEditable = true"); + page.runJavaScript("document.documentElement.contentEditable = true"); \endcode @@ -287,7 +287,7 @@ \li QWebPage::setContentEditable \li In the latest HTML standard, any document element can be made editable through the \c contentEditable attribute. So \c runJavaScript is all that is needed: - \c{page->runJavascript("document.documentElement.contentEditable = true")} + \c{page->runJavaScript("document.documentElement.contentEditable = true")} \row \li QWebPage::setLinkDelegationPolicy \li There is no way to connect a signal to run C++ code when a link is clicked. However, diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc index fab4827a0..539e809d4 100644 --- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc @@ -281,6 +281,9 @@ the user clicks on the web page with the right mouse button. It is called from the default \l{QWidget::}{contextMenuEvent()} handler. The popup menu's ownership is transferred to the caller. + + Returns \c nullptr if the context menu data is not initialized, for example when it + is called when there is actually no context menu requested. */ /*! @@ -411,14 +414,14 @@ \fn void QWebEnginePage::findText(const QString &subString, FindFlags options) Finds the specified string, \a subString, in the page, using the given \a options. - To clear the selection, just pass an empty string. + To clear the search highlight, just pass an empty string. */ /*! \fn void QWebEnginePage::findText(const QString &subString, FindFlags options, FunctorOrLambda resultCallback) Finds the specified string, \a subString, in the page, using the given \a options. - To clear the selection, just pass an empty string. + To clear the search highlight, just pass an empty string. The \a resultCallback must take a boolean parameter. It will be called with a value of \c true if the \a subString was found; otherwise the callback value will be \c false. @@ -615,6 +618,10 @@ \warning This function works only for HTML, for other mime types (such as XHTML and SVG) setContent() should be used instead. + \warning The content will be percent encoded before being sent to the renderer via IPC. + This may increase its size. The maximum size of the percent encoded content is + 2 megabytes minus 30 bytes. + \sa toHtml(), setContent(), load() */ @@ -630,6 +637,10 @@ \note This method will not affect session or global history for the page. + \warning The content will be percent encoded before being sent to the renderer via IPC. + This may increase its size. The maximum size of the percent encoded content is + 2 megabytes minus 6 bytes plus the length of the mime type string. + \sa toHtml(), setHtml() */ diff --git a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc index 3e0f4cf82..558aa1f50 100644 --- a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc @@ -88,7 +88,8 @@ This enum type specifies settings for web pages: \value AutoLoadImages - Automatically loads images on web pages. Enabled by default. + Automatically dowloads images for web pages. When this setting is + disabled, images are loaded from the cache. Enabled by default. \value JavascriptEnabled Enables the running of JavaScript programs. Enabled by default. \value JavascriptCanOpenWindows @@ -130,7 +131,7 @@ Enables displaying the built-in error pages of Chromium. Enabled by default. \value PluginsEnabled Enables support for Pepper plugins, such as the Flash player. Disabled by default. - See also \l{Pepper Plugin API Support}. (Added in Qt 5.6) + See also \l{Pepper Plugin API}. (Added in Qt 5.6) \value FullScreenSupportEnabled Enables fullscreen support in an application. Disabled by default. (Added in Qt 5.6) \value ScreenCaptureEnabled 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 3f70187e7..99621b602 100644 --- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp +++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp @@ -298,6 +298,34 @@ void RenderWidgetHostViewQtDelegateWidget::hideEvent(QHideEvent *event) bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event) { bool handled = false; + + // Mimic QWidget::event() by ignoring mouse, keyboard, touch and tablet events if the widget is + // disabled. + if (!isEnabled()) { + switch (event->type()) { + case QEvent::TabletPress: + case QEvent::TabletRelease: + case QEvent::TabletMove: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::MouseMove: + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + case QEvent::TouchCancel: + case QEvent::ContextMenu: + case QEvent::KeyPress: + case QEvent::KeyRelease: +#ifndef QT_NO_WHEELEVENT + case QEvent::Wheel: +#endif + return false; + default: + break; + } + } + if (event->type() == QEvent::MouseButtonDblClick) { // QWidget keeps the Qt4 behavior where the DblClick event would replace the Press event. // QtQuick is different by sending both the Press and DblClick events for the second press |