diff options
49 files changed, 329 insertions, 69 deletions
diff --git a/config.tests/re2/re2.cpp b/config.tests/re2/re2.cpp index f2c0b0170..bd3b80a82 100644 --- a/config.tests/re2/re2.cpp +++ b/config.tests/re2/re2.cpp @@ -30,6 +30,7 @@ int main(int, char **) { - RE2 re2("dummytest"); + std::string s("dummytest"); + RE2 re2(s); return 0; } diff --git a/dist/changes-5.12.0 b/dist/changes-5.12.0 new file mode 100644 index 000000000..557bdf0a9 --- /dev/null +++ b/dist/changes-5.12.0 @@ -0,0 +1,84 @@ +Qt 5.12 introduces many new features and improvements as well as bugfixes +over the 5.11.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + + +**************************************************************************** +* General * +**************************************************************************** + +Chromium Snapshot +----------------- + +- Updated the Chromium version to 69.0.3497.128 +- Applied security fixes from Chrome up to version 70.0.3538.102 + + +Core library changes +-------------------- + +- [QTBUG-51631, QTBUG-65682] Both Linux desktop and embedded now use Ozone + internally, to be more consistent and better support Wayland. +- [QTBUG-66068] Stopped creating the default profile if the user didn't use it. +- [QTBUG-69442] Fixed swapping of Control/Meta on macOS, an improved keycode + conversion on all platforms. +- [QTBUG-70288] Fixed suggested filenames of non-ASCII downloaded items, + when encoding is implicit. +- The internal chrome://accessibility page is now supported. + + +Build System +------------ + +- Updated macOS build requirements to macOS 10.12, macOS SDK 10.12, Xcode + 8.3.3. +- QtWebChannel is now an optional dependency. +- [QTBUG-51082] Kerberos support can now be enabled. +- [QTBUG-70183] Fixed building with system libvpx. + + +**************************************************************************** +* Libraries * +**************************************************************************** + +Qt WebEngineCore +---------------- + +- [QTBUG-62536] Added the QWebEngineUrlScheme class for configuring how + custom schemes are parsed and which security restrictions should apply. + + +Qt WebEngine (QML) +------------------ + +- WebEngineSettings::dnsPrefetchEnabled added, but disabled by default. +- WebEngineDownloadItem::view accessor added to tell were the download was triggered. +- [QTBUG-56117] Introduce WebEngineAction in Quick API. +- [QTBUG-53745, QTBUG-69237] WebEngineView::printRequest added for window.print() support. + + + Qt WebEngineWidgets +------------------- + +- QWebEngineSettings::DnsPrefetchEnabled added, but disabled by default. +- QWebEngineSettings::XSSAuditingEnabled is now enabled by default, to mirror + Chromium's behavior. +- QWebEngineDownloadItem::page() accessor added to tell were the download was triggered. +- [QTBUG-53745, QTBUG-69237] QWebEnginePage::printRequest added for window.print() support. +- [QTBUG-54877] Introduced support for client certificates on macOS and Windows. +- [QTBUG-64501] Fixed a way to trigger an infinite loop. +- [QTBUG-69222] Fixed call order of print callback. + diff --git a/examples/webengine/customdialogs/main.cpp b/examples/webengine/customdialogs/main.cpp index dea664c59..35f39211d 100644 --- a/examples/webengine/customdialogs/main.cpp +++ b/examples/webengine/customdialogs/main.cpp @@ -65,6 +65,7 @@ typedef QGuiApplication Application; int main(int argc, char *argv[]) { + QCoreApplication::setOrganizationName("QtExamples"); Application app(argc, argv); QtWebEngine::initialize(); diff --git a/examples/webengine/minimal/doc/src/minimal.qdoc b/examples/webengine/minimal/doc/src/minimal.qdoc index e021a81d1..8d12afc7c 100644 --- a/examples/webengine/minimal/doc/src/minimal.qdoc +++ b/examples/webengine/minimal/doc/src/minimal.qdoc @@ -50,9 +50,15 @@ \skipto #include \printto main - In the \c main function we first set the Qt::AA_EnableHighDpiScaling - attribute. This lets the web view automatically scale on high-dpi displays. - Then we instantiate a QGuiApplication object. + In the \c main function we first set the + \l{QCoreApplication::organizationName} property. This affects the locations + where Qt WebEngine stores persistent and cached data (see also + \l{WebEngineProfile::cachePath} and + \l{WebEngineProfile::persistentStoragePath}). + + We also set the Qt::AA_EnableHighDpiScaling attribute. This lets the web + view automatically scale on high-dpi displays. Then we instantiate a + QGuiApplication object. Next, we call \l{QtWebEngine::initialize}, which makes sure that OpenGL contexts can be shared between the main process and the dedicated renderer diff --git a/examples/webengine/minimal/main.cpp b/examples/webengine/minimal/main.cpp index 21a15d19c..9db6ea6aa 100644 --- a/examples/webengine/minimal/main.cpp +++ b/examples/webengine/minimal/main.cpp @@ -54,6 +54,7 @@ int main(int argc, char *argv[]) { + QCoreApplication::setOrganizationName("QtExamples"); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); diff --git a/examples/webengine/quicknanobrowser/main.cpp b/examples/webengine/quicknanobrowser/main.cpp index 63725d3e2..18ba7b3e2 100644 --- a/examples/webengine/quicknanobrowser/main.cpp +++ b/examples/webengine/quicknanobrowser/main.cpp @@ -78,6 +78,7 @@ static QUrl startupUrl() int main(int argc, char **argv) { + QCoreApplication::setOrganizationName("QtExamples"); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); Application app(argc, argv); diff --git a/examples/webengine/recipebrowser/main.cpp b/examples/webengine/recipebrowser/main.cpp index 284f75a72..6e6d69804 100644 --- a/examples/webengine/recipebrowser/main.cpp +++ b/examples/webengine/recipebrowser/main.cpp @@ -56,6 +56,7 @@ int main(int argc, char *argv[]) { + QCoreApplication::setOrganizationName("QtExamples"); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QtWebEngine::initialize(); diff --git a/examples/webenginewidgets/contentmanipulation/main.cpp b/examples/webenginewidgets/contentmanipulation/main.cpp index e816079d2..417b87184 100644 --- a/examples/webenginewidgets/contentmanipulation/main.cpp +++ b/examples/webenginewidgets/contentmanipulation/main.cpp @@ -54,6 +54,7 @@ int main(int argc, char * argv[]) { + QCoreApplication::setOrganizationName("QtExamples"); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication app(argc, argv); diff --git a/examples/webenginewidgets/cookiebrowser/main.cpp b/examples/webenginewidgets/cookiebrowser/main.cpp index 0ae5433ba..2a7fe6362 100644 --- a/examples/webenginewidgets/cookiebrowser/main.cpp +++ b/examples/webenginewidgets/cookiebrowser/main.cpp @@ -54,6 +54,7 @@ int main(int argc, char *argv[]) { + QCoreApplication::setOrganizationName("QtExamples"); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication app(argc, argv); MainWindow window(QUrl("http://qt.io")); diff --git a/examples/webenginewidgets/html2pdf/html2pdf.cpp b/examples/webenginewidgets/html2pdf/html2pdf.cpp index 5e293261f..e9fc69534 100644 --- a/examples/webenginewidgets/html2pdf/html2pdf.cpp +++ b/examples/webenginewidgets/html2pdf/html2pdf.cpp @@ -119,6 +119,7 @@ void Html2PdfConverter::pdfPrintingFinished(const QString &filePath, bool succes int main(int argc, char *argv[]) { QApplication app(argc, argv); + QCoreApplication::setOrganizationName("QtExamples"); QCoreApplication::setApplicationName("html2pdf"); QCoreApplication::setApplicationVersion(QT_VERSION_STR); diff --git a/examples/webenginewidgets/maps/main.cpp b/examples/webenginewidgets/maps/main.cpp index cad9c7ea9..cfcfa06d8 100644 --- a/examples/webenginewidgets/maps/main.cpp +++ b/examples/webenginewidgets/maps/main.cpp @@ -53,6 +53,7 @@ int main(int argc, char *argv[]) { + QCoreApplication::setOrganizationName("QtExamples"); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication app(argc, argv); diff --git a/examples/webenginewidgets/markdowneditor/main.cpp b/examples/webenginewidgets/markdowneditor/main.cpp index de2dee605..b7a7905be 100644 --- a/examples/webenginewidgets/markdowneditor/main.cpp +++ b/examples/webenginewidgets/markdowneditor/main.cpp @@ -56,6 +56,7 @@ int main(int argc, char *argv[]) { + QCoreApplication::setOrganizationName("QtExamples"); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication a(argc, argv); diff --git a/examples/webenginewidgets/minimal/doc/src/minimal.qdoc b/examples/webenginewidgets/minimal/doc/src/minimal.qdoc index 05ec9ee79..477ff521b 100644 --- a/examples/webenginewidgets/minimal/doc/src/minimal.qdoc +++ b/examples/webenginewidgets/minimal/doc/src/minimal.qdoc @@ -42,8 +42,14 @@ \section1 The Code - In the \c main function we first set the Qt::AA_EnableHighDpiScaling. - This lets the web view automatically scale on high-dpi displays. + In the \c main function we first set the + \l{QCoreApplication::organizationName} property. This affects the locations + where Qt WebEngine stores persistent and cached data (see also + \l{QWebEngineProfile::cachePath} and + \l{QWebEngineProfile::persistentStoragePath}). + + We also set the Qt::AA_EnableHighDpiScaling attribute. This lets the web + view automatically scale on high-dpi displays. Next, we instantiate a QApplication and a QWebEngineView. The URL to load is taken from the command-line in \c commandLineUrlArgument and diff --git a/examples/webenginewidgets/minimal/main.cpp b/examples/webenginewidgets/minimal/main.cpp index f58e4d54a..b31382ad5 100644 --- a/examples/webenginewidgets/minimal/main.cpp +++ b/examples/webenginewidgets/minimal/main.cpp @@ -63,6 +63,7 @@ QUrl commandLineUrlArgument() int main(int argc, char *argv[]) { + QCoreApplication::setOrganizationName("QtExamples"); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication app(argc, argv); diff --git a/examples/webenginewidgets/simplebrowser/main.cpp b/examples/webenginewidgets/simplebrowser/main.cpp index 5a8a0e65d..7b77a4bd2 100644 --- a/examples/webenginewidgets/simplebrowser/main.cpp +++ b/examples/webenginewidgets/simplebrowser/main.cpp @@ -67,6 +67,7 @@ QUrl commandLineUrlArgument() int main(int argc, char **argv) { + QCoreApplication::setOrganizationName("QtExamples"); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); diff --git a/examples/webenginewidgets/spellchecker/main.cpp b/examples/webenginewidgets/spellchecker/main.cpp index 90602f859..c2951fe00 100644 --- a/examples/webenginewidgets/spellchecker/main.cpp +++ b/examples/webenginewidgets/spellchecker/main.cpp @@ -53,6 +53,7 @@ int main(int argc, char *argv[]) { + QCoreApplication::setOrganizationName("QtExamples"); QApplication app(argc, argv); WebView view; diff --git a/examples/webenginewidgets/stylesheetbrowser/main.cpp b/examples/webenginewidgets/stylesheetbrowser/main.cpp index 54fce0ce3..833ea6bb0 100644 --- a/examples/webenginewidgets/stylesheetbrowser/main.cpp +++ b/examples/webenginewidgets/stylesheetbrowser/main.cpp @@ -55,12 +55,9 @@ int main(int argc, char *argv[]) { - QCoreApplication::setOrganizationName("The Qt Company"); - QCoreApplication::setOrganizationDomain("www.qt.io"); - QCoreApplication::setApplicationName("StyleSheet Browser"); - qRegisterMetaTypeStreamOperators<StyleSheet>("StyleSheet"); + QCoreApplication::setOrganizationName("QtExamples"); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication a(argc, argv); MainWindow w(QUrl("http://qt.io")); diff --git a/examples/webenginewidgets/videoplayer/main.cpp b/examples/webenginewidgets/videoplayer/main.cpp index cad9c7ea9..cfcfa06d8 100644 --- a/examples/webenginewidgets/videoplayer/main.cpp +++ b/examples/webenginewidgets/videoplayer/main.cpp @@ -53,6 +53,7 @@ int main(int argc, char *argv[]) { + QCoreApplication::setOrganizationName("QtExamples"); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication app(argc, argv); diff --git a/examples/webenginewidgets/webui/main.cpp b/examples/webenginewidgets/webui/main.cpp index 3e9f61fe4..0f6a3e87e 100644 --- a/examples/webenginewidgets/webui/main.cpp +++ b/examples/webenginewidgets/webui/main.cpp @@ -57,6 +57,7 @@ int main(int argc, char *argv[]) { + QCoreApplication::setOrganizationName("QtExamples"); QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); WebUiHandler::registerUrlScheme(); diff --git a/mkspecs/features/gn_generator.prf b/mkspecs/features/gn_generator.prf index 88f64fa91..c1399a453 100644 --- a/mkspecs/features/gn_generator.prf +++ b/mkspecs/features/gn_generator.prf @@ -208,6 +208,18 @@ GN_CONTENTS += " if (!defined(deps)) {"\ GN_CONTENTS += " ]" } +# Remove the default no_rtti config for our own cpp files, thus leaving the decision +# to the compiler's defaults. This is consistent with how qtbase does it. +# Unless the user explicitly configured Qt with a different RTTI setting. +# Windows only for now, because macOS (and presumably Linux) does not support +# partial rtti info (e.g. rtti info present for derived class, but not base class), and the +# qtbase rtti feature affects only Windows. +win32 { + GN_CONTENTS += " configs -= [\"//build/config/compiler:no_rtti\"]" + CONFIG(rtti_off): GN_CONTENTS += " configs += [\"//build/config/compiler:no_rtti\"]" + CONFIG(rtti): GN_CONTENTS += " configs += [\"//build/config/compiler:rtti\"]" +} + GN_CONTENTS += " if (moc_source_h_files != []) {" GN_CONTENTS += " deps += [" GN_CONTENTS += " \":generate_h_mocs\"," diff --git a/src/3rdparty b/src/3rdparty -Subproject d521ec6dd1ed0114b9c6d32b047fb024420a6cd +Subproject 91432e048e9bef479cc61f97d6ab4599121a199 diff --git a/src/core/compositor/compositor.cpp b/src/core/compositor/compositor.cpp index 2d955b917..77a973748 100644 --- a/src/core/compositor/compositor.cpp +++ b/src/core/compositor/compositor.cpp @@ -41,15 +41,17 @@ #include "compositor_resource_tracker.h" #include "delegated_frame_node.h" +#include "render_widget_host_view_qt.h" -#include <components/viz/common/resources/returned_resource.h> -#include <content/public/browser/browser_thread.h> -#include <services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h> +#include "components/viz/common/resources/returned_resource.h" +#include "content/public/browser/browser_thread.h" +#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h" namespace QtWebEngineCore { -Compositor::Compositor() +Compositor::Compositor(RenderWidgetHostViewQt *hostView) : m_resourceTracker(new CompositorResourceTracker) + , m_view(hostView) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -169,6 +171,7 @@ bool Compositor::OnBeginFrameDerivedImpl(const viz::BeginFrameArgs &args) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + m_view->OnBeginFrame(args.frame_time); m_beginFrameSource->OnUpdateVSyncParameters(args.frame_time, args.interval); if (m_frameSinkClient) m_frameSinkClient->OnBeginFrame(args); diff --git a/src/core/compositor/compositor.h b/src/core/compositor/compositor.h index d34255d26..b025f901d 100644 --- a/src/core/compositor/compositor.h +++ b/src/core/compositor/compositor.h @@ -64,6 +64,7 @@ class CompositorFrameSinkClient; namespace QtWebEngineCore { class CompositorResourceTracker; +class RenderWidgetHostViewQt; class RenderWidgetHostViewQtDelegate; // Receives viz::CompositorFrames from child compositors and provides QSGNodes @@ -87,7 +88,7 @@ class RenderWidgetHostViewQtDelegate; class Compositor final : private viz::BeginFrameObserverBase { public: - explicit Compositor(); + explicit Compositor(RenderWidgetHostViewQt *hostView); ~Compositor() override; void setFrameSinkClient(viz::mojom::CompositorFrameSinkClient *frameSinkClient); @@ -109,6 +110,7 @@ private: viz::CompositorFrame m_pendingFrame; base::OnceClosure m_submitCallback; std::unique_ptr<CompositorResourceTracker> m_resourceTracker; + RenderWidgetHostViewQt *m_view; std::unique_ptr<viz::SyntheticBeginFrameSource> m_beginFrameSource; viz::mojom::CompositorFrameSinkClient *m_frameSinkClient = nullptr; bool m_updatePaintNodeShouldCommit = false; diff --git a/src/core/config/common.pri b/src/core/config/common.pri index 6b79a1f99..ddb4ca4bf 100644 --- a/src/core/config/common.pri +++ b/src/core/config/common.pri @@ -23,7 +23,8 @@ gn_args += \ !win32: gn_args += \ use_jumbo_build=true \ - jumbo_file_merge_limit=8 + jumbo_file_merge_limit=8 \ + jumbo_build_excluded="[\"browser\"]" qtConfig(webengine-printing-and-pdf) { gn_args += enable_basic_printing=true enable_print_preview=true diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri index eb8bb7bb0..ed7745b89 100644 --- a/src/core/config/linux.pri +++ b/src/core/config/linux.pri @@ -147,7 +147,6 @@ host_build { gn_args += use_system_libpng=true qtConfig(webengine-printing-and-pdf): gn_args += pdfium_use_system_libpng=true } - qtConfig(webengine-system-png): gn_args += use_system_libpng=true qtConfig(webengine-system-jpeg): gn_args += use_system_libjpeg=true qtConfig(webengine-system-freetype): gn_args += use_system_freetype=true qtConfig(webengine-system-harfbuzz): gn_args += use_system_harfbuzz=true diff --git a/src/core/ozone/gl_ozone_glx_qt.cpp b/src/core/ozone/gl_ozone_glx_qt.cpp index 2e7a28a0e..e3a4f4708 100644 --- a/src/core/ozone/gl_ozone_glx_qt.cpp +++ b/src/core/ozone/gl_ozone_glx_qt.cpp @@ -44,18 +44,12 @@ #include <QGuiApplication> #include "gl_ozone_glx_qt.h" #include "gl_surface_glx_qt.h" +#include "gl_context_qt.h" #include "ui/gl/gl_context_glx.h" #include "ui/gl/gl_gl_api_implementation.h" #include "ui/gl/gl_glx_api_implementation.h" #include <dlfcn.h> -#ifndef QT_NO_OPENGL -#include <QOpenGLContext> -QT_BEGIN_NAMESPACE -Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context(); -QT_END_NAMESPACE -#endif - namespace ui { bool GLOzoneGLXQt::InitializeGLOneOffPlatform() { @@ -79,16 +73,12 @@ bool GLOzoneGLXQt::InitializeStaticGLBindings( reinterpret_cast<gl::GLGetProcAddressProc>( base::GetFunctionPointerFromNativeLibrary(library, "glXGetProcAddress")); - -#ifndef QT_NO_OPENGL if (!get_proc_address) { // glx handle not loaded, fallback to qpa - if (QOpenGLContext *context = qt_gl_global_share_context()) { - get_proc_address = reinterpret_cast<gl::GLGetProcAddressProc>( - context->getProcAddress("glXGetProcAddress")); - } + QFunctionPointer address = GLContextHelper::getGlXGetProcAddress(); + get_proc_address = reinterpret_cast<gl::GLGetProcAddressProc>(address); } -#endif + if (!get_proc_address) { LOG(ERROR) << "glxGetProcAddress not found."; base::UnloadNativeLibrary(library); diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index bac9dd6cf..31a145b44 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -53,6 +53,7 @@ #include "content/browser/frame_host/render_frame_host_impl.h" #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/common/cursors/webcursor.h" #include "content/common/input_messages.h" #include "third_party/skia/include/core/SkColor.h" @@ -260,7 +261,7 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget , m_gestureProvider(QtGestureProviderConfig(), this) , m_sendMotionActionDown(false) , m_touchMotionStarted(false) - , m_compositor(new Compositor) + , m_compositor(new Compositor(this)) , m_loadVisuallyCommittedState(NotCommitted) , m_adapterClient(0) , m_imeInProgress(false) @@ -402,7 +403,18 @@ bool RenderWidgetHostViewQt::HasFocus() const bool RenderWidgetHostViewQt::IsSurfaceAvailableForCopy() const { - return false; + return true; +} + +void RenderWidgetHostViewQt::CopyFromSurface(const gfx::Rect &src_rect, + const gfx::Size &output_size, + base::OnceCallback<void(const SkBitmap &)> callback) +{ + QImage image; + if (m_delegate->copySurface(toQt(src_rect), toQt(output_size), image)) + std::move(callback).Run(toSkBitmap(image)); + else + std::move(callback).Run(SkBitmap()); } void RenderWidgetHostViewQt::Show() @@ -870,6 +882,13 @@ void RenderWidgetHostViewQt::selectionChanged() void RenderWidgetHostViewQt::OnGestureEvent(const ui::GestureEventData& gesture) { + if ((gesture.type() == ui::ET_GESTURE_PINCH_BEGIN + || gesture.type() == ui::ET_GESTURE_PINCH_UPDATE + || gesture.type() == ui::ET_GESTURE_PINCH_END) + && !content::IsPinchToZoomEnabled()) { + return; + } + host()->ForwardGestureEvent(ui::CreateWebGestureEventFromGestureEventData(gesture)); } @@ -1627,6 +1646,11 @@ void RenderWidgetHostViewQt::SetNeedsBeginFrames(bool needs_begin_frames) m_compositor->setNeedsBeginFrames(needs_begin_frames); } +void RenderWidgetHostViewQt::OnBeginFrame(base::TimeTicks frame_time) +{ + host()->ProgressFlingIfNeeded(frame_time); +} + content::RenderFrameHost *RenderWidgetHostViewQt::getFocusedFrameHost() { content::RenderViewHostImpl *viewHost = content::RenderViewHostImpl::From(host()); diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h index 6a1134ac0..6dd4d57e5 100644 --- a/src/core/render_widget_host_view_qt.h +++ b/src/core/render_widget_host_view_qt.h @@ -112,6 +112,7 @@ public: RenderWidgetHostViewQtDelegate *delegate() { return m_delegate.get(); } void setDelegate(RenderWidgetHostViewQtDelegate *delegate); void setAdapterClient(WebContentsAdapterClient *adapterClient); + void OnBeginFrame(base::TimeTicks frame_time); void InitAsChild(gfx::NativeView) override; void InitAsPopup(content::RenderWidgetHostView*, const gfx::Rect&) override; @@ -124,6 +125,9 @@ public: void Focus() override; bool HasFocus() const override; bool IsSurfaceAvailableForCopy() const override; + void CopyFromSurface(const gfx::Rect &src_rect, + const gfx::Size &output_size, + base::OnceCallback<void(const SkBitmap &)> callback) override; void Show() override; void Hide() override; bool IsShowing() override; diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h index 991c26ea8..5ce595502 100644 --- a/src/core/render_widget_host_view_qt_delegate.h +++ b/src/core/render_widget_host_view_qt_delegate.h @@ -114,6 +114,7 @@ public: virtual void inputMethodStateChanged(bool editorVisible, bool passwordInput) = 0; virtual void setInputMethodHints(Qt::InputMethodHints hints) = 0; virtual void setClearColor(const QColor &color) = 0; + virtual bool copySurface(const QRect &, const QSize &, QImage &) = 0; }; } // namespace QtWebEngineCore diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp index 3eda3993a..403448b91 100644 --- a/src/core/renderer/content_renderer_client_qt.cpp +++ b/src/core/renderer/content_renderer_client_qt.cpp @@ -213,8 +213,9 @@ void ContentRendererClientQt::PrepareErrorPageForHttpStatusError(content::Render errorHtml, errorDescription); } -void ContentRendererClientQt::GetNavigationErrorStringsInternal(content::RenderFrame */*renderFrame*/, const blink::WebURLRequest &failedRequest, const error_page::Error &error, std::string *errorHtml, base::string16 *errorDescription) +void ContentRendererClientQt::GetNavigationErrorStringsInternal(content::RenderFrame *renderFrame, const blink::WebURLRequest &failedRequest, const error_page::Error &error, std::string *errorHtml, base::string16 *errorDescription) { + Q_UNUSED(renderFrame) const bool isPost = QByteArray::fromStdString(failedRequest.HttpMethod().Utf8()) == QByteArrayLiteral("POST"); if (errorHtml) { @@ -424,8 +425,6 @@ static void AddWidevine(std::vector<std::unique_ptr<media::KeySystemProperties>> return; } - media::SupportedCodecs supported_codecs = media::EME_CODEC_NONE; - // Codecs and encryption schemes. auto codecs = GetSupportedCodecs(capability->video_codecs, /*is_secure=*/false); @@ -452,8 +451,6 @@ static void AddWidevine(std::vector<std::unique_ptr<media::KeySystemProperties>> return; } - bool cdm_supports_persistent_license = - base::ContainsValue(capability->session_types, media::CdmSessionType::kPersistentLicense); auto persistent_license_support = media::EmeSessionTypeSupport::NOT_SUPPORTED; auto persistent_usage_record_support = media::EmeSessionTypeSupport::NOT_SUPPORTED; diff --git a/src/core/type_conversion.cpp b/src/core/type_conversion.cpp index 4aff2cff6..d35426ac3 100644 --- a/src/core/type_conversion.cpp +++ b/src/core/type_conversion.cpp @@ -137,6 +137,44 @@ QImage toQImage(const gfx::ImageSkiaRep &imageSkiaRep) return image; } +SkBitmap toSkBitmap(const QImage &image) +{ + SkBitmap bitmap; + SkImageInfo imageInfo; + + switch (image.format()) { + case QImage::Format_RGB32: + imageInfo = SkImageInfo::Make(image.width(), image.height(), kBGRA_8888_SkColorType, kOpaque_SkAlphaType); + break; + case QImage::Format_ARGB32: + imageInfo = SkImageInfo::Make(image.width(), image.height(), kBGRA_8888_SkColorType, kUnpremul_SkAlphaType); + break; + case QImage::Format_ARGB32_Premultiplied: + imageInfo = SkImageInfo::Make(image.width(), image.height(), kBGRA_8888_SkColorType, kPremul_SkAlphaType); + break; + case QImage::Format_RGBX8888: + imageInfo = SkImageInfo::Make(image.width(), image.height(), kRGBA_8888_SkColorType, kOpaque_SkAlphaType); + break; + case QImage::Format_RGBA8888: + imageInfo = SkImageInfo::Make(image.width(), image.height(), kRGBA_8888_SkColorType, kUnpremul_SkAlphaType); + break; + case QImage::Format_RGBA8888_Premultiplied: + imageInfo = SkImageInfo::Make(image.width(), image.height(), kRGBA_8888_SkColorType, kPremul_SkAlphaType); + break; + default: + return toSkBitmap(image.convertToFormat(QImage::Format_ARGB32_Premultiplied)); + } + + bitmap.installPixels(imageInfo, (void *)image.bits(), image.bytesPerLine()); + + // Ensure we copy the pixels + SkBitmap bitmapCopy; + bitmapCopy.allocPixels(imageInfo); + bitmapCopy.writePixels(bitmap.pixmap()); + + return bitmapCopy; +} + QIcon toQIcon(const std::vector<SkBitmap> &bitmaps) { if (!bitmaps.size()) diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h index b9e210c22..afc3c3336 100644 --- a/src/core/type_conversion.h +++ b/src/core/type_conversion.h @@ -194,6 +194,8 @@ inline QImage toQImage(const SkBitmap &bitmap, QImage::Format format) QImage toQImage(const SkBitmap &bitmap); QImage toQImage(const gfx::ImageSkiaRep &imageSkiaRep); +SkBitmap toSkBitmap(const QImage &image); + QIcon toQIcon(const std::vector<SkBitmap> &bitmaps); inline QMatrix4x4 toQt(const SkMatrix44 &m) diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 096568570..f9d9631fd 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -449,6 +449,8 @@ WebEngineContext::WebEngineContext() appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kEnableSurfaceSynchronization.name); // The video-capture service is not functioning at this moment (since 69) appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kMojoVideoCapture.name); + // We do not yet support the internal video capture API. + appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, features::kUseVideoCaptureApiForDevToolsSnapshots.name); if (useEmbeddedSwitches) { // embedded switches are based on the switches for Android, see content/browser/android/content_startup_flags.cc diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 3bc0be196..d9667a643 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -1844,6 +1844,7 @@ QQuickWebEngineAction *QQuickWebEngineView::action(WebAction action) break; case Stop: text = tr("Stop"); + iconName = QStringLiteral("process-stop"); break; case Reload: text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Reload); @@ -1851,28 +1852,35 @@ QQuickWebEngineAction *QQuickWebEngineView::action(WebAction action) break; case ReloadAndBypassCache: text = tr("Reload and Bypass Cache"); + iconName = QStringLiteral("view-refresh"); break; case Cut: text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Cut); - iconName = QStringLiteral("Cut"); + iconName = QStringLiteral("edit-cut"); break; case Copy: text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Copy); + iconName = QStringLiteral("edit-copy"); break; case Paste: text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Paste); + iconName = QStringLiteral("edit-paste"); break; case Undo: text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Undo); + iconName = QStringLiteral("edit-undo"); break; case Redo: text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Redo); + iconName = QStringLiteral("edit-redo"); break; case SelectAll: text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::SelectAll); + iconName = QStringLiteral("edit-select-all"); break; case PasteAndMatchStyle: text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::PasteAndMatchStyle); + iconName = QStringLiteral("edit-paste"); break; case OpenLinkInThisWindow: text = tr("Open link in this window"); @@ -1909,9 +1917,11 @@ QQuickWebEngineAction *QQuickWebEngineView::action(WebAction action) break; case ToggleMediaPlayPause: text = tr("Toggle Play/Pause"); + iconName = QStringLiteral("media-playback-start"); break; case ToggleMediaMute: text = tr("Toggle Mute"); + iconName = QStringLiteral("audio-volume-muted"); break; case DownloadMediaToDisk: text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadMediaToDisk); @@ -1921,31 +1931,38 @@ QQuickWebEngineAction *QQuickWebEngineView::action(WebAction action) break; case ExitFullScreen: text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ExitFullScreen); + iconName = QStringLiteral("view-fullscreen"); break; case RequestClose: text = tr("Close Page"); + iconName = QStringLiteral("window-close"); break; case Unselect: text = tr("Unselect"); + iconName = QStringLiteral("edit-select-none"); break; case SavePage: text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::SavePage); + iconName = QStringLiteral("document-save"); break; case ViewSource: text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ViewSource); - iconName = QStringLiteral("view-source"); break; case ToggleBold: text = tr("&Bold"); + iconName = QStringLiteral("format-text-bold"); break; case ToggleItalic: text = tr("&Italic"); + iconName = QStringLiteral("format-text-italic"); break; case ToggleUnderline: text = tr("&Underline"); + iconName = QStringLiteral("format-text-underline"); break; case ToggleStrikethrough: text = tr("&Strikethrough"); + iconName = QStringLiteral("format-text-strikethrough"); break; case AlignLeft: text = tr("Align &Left"); @@ -1961,9 +1978,11 @@ QQuickWebEngineAction *QQuickWebEngineView::action(WebAction action) break; case Indent: text = tr("&Indent"); + iconName = QStringLiteral("format-indent-more"); break; case Outdent: text = tr("&Outdent"); + iconName = QStringLiteral("format-indent-less"); break; case InsertOrderedList: text = tr("Insert &Ordered List"); diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc index 9c2cbb414..bd5569e3f 100644 --- a/src/webengine/doc/src/qtwebengine-overview.qdoc +++ b/src/webengine/doc/src/qtwebengine-overview.qdoc @@ -89,7 +89,7 @@ \l{https://chromium.googlesource.com/chromium/src/+/master/docs/chromium_browser_vs_google_chrome.md}{overview} that is part of the documentation in the \l {Chromium Project} upstream source tree. - This version of Qt WebEngine is based on Chromium version 65.0.3325.151, with + This version of Qt WebEngine is based on Chromium version 69.0.3497.128, with additional security fixes from newer versions. \section2 Qt WebEngine Process diff --git a/src/webengine/plugin/qmldir b/src/webengine/plugin/qmldir index e24f55ed9..8970dc9c1 100644 --- a/src/webengine/plugin/qmldir +++ b/src/webengine/plugin/qmldir @@ -1,3 +1,4 @@ module QtWebEngine plugin qtwebengineplugin +classname QtWebEnginePlugin typeinfo plugins.qmltypes diff --git a/src/webengine/plugin/testsupport/qmldir b/src/webengine/plugin/testsupport/qmldir index 588c9d2d4..7fff80251 100644 --- a/src/webengine/plugin/testsupport/qmldir +++ b/src/webengine/plugin/testsupport/qmldir @@ -1,3 +1,4 @@ module QtWebEngine.testsupport plugin qtwebenginetestsupportplugin +classname QtWebEngineTestSupportPlugin typeinfo plugins.qmltypes 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 d23e64774..1176573fd 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp +++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp @@ -327,8 +327,7 @@ void RenderWidgetHostViewQtDelegateQuick::geometryChanged(const QRectF &newGeome QQuickItem::geometryChanged(newGeometry, oldGeometry); if (window()) { - // TODO(pvarga): Use QQuickItem::mapToGlobal from Qt 5.7 - const QPoint globalPos = window()->mapToGlobal(position().toPoint()); + const QPointF globalPos = QQuickItem::mapToGlobal(position()); if (globalPos != m_lastGlobalPos) { m_lastGlobalPos = globalPos; m_client->windowBoundsChanged(); @@ -366,10 +365,8 @@ QSGNode *RenderWidgetHostViewQtDelegateQuick::updatePaintNode(QSGNode *oldNode, void RenderWidgetHostViewQtDelegateQuick::onWindowPosChanged() { - if (window()) { - // TODO(pvarga): Use QQuickItem::mapToGlobal from Qt 5.7 - m_lastGlobalPos = window()->mapToGlobal(position().toPoint()); - } + if (window()) + m_lastGlobalPos = QQuickItem::mapToGlobal(position()); m_client->windowBoundsChanged(); } @@ -379,4 +376,15 @@ void RenderWidgetHostViewQtDelegateQuick::onHide() m_client->forwardEvent(&event); } +bool RenderWidgetHostViewQtDelegateQuick::copySurface(const QRect &rect, const QSize &size, QImage &image) +{ + image = QQuickItem::window()->grabWindow(); + if (image.isNull()) + return false; + QRect subrect = !rect.isEmpty() ? rect : image.rect(); + image = image.copy(subrect); + image = image.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + return true; +} + } // namespace QtWebEngineCore 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 6b855c824..6f6cd1509 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quick.h +++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h @@ -82,6 +82,7 @@ public: void setInputMethodHints(Qt::InputMethodHints) override { } // The QtQuick view doesn't have a backbuffer of its own and doesn't need this void setClearColor(const QColor &) override { } + bool copySurface(const QRect &rect, const QSize &size, QImage &image) override; protected: bool event(QEvent *event) override; @@ -113,7 +114,7 @@ private: QList<QMetaObject::Connection> m_windowConnections; bool m_isPopup; bool m_isPasswordInput; - QPoint m_lastGlobalPos; + QPointF m_lastGlobalPos; QQuickWebEngineView *m_view = nullptr; }; 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 df241bf3a..36e4ddd8a 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h +++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h @@ -78,6 +78,7 @@ public: void inputMethodStateChanged(bool, bool) override {} void setInputMethodHints(Qt::InputMethodHints) override { } void setClearColor(const QColor &) override { } + bool copySurface(const QRect &, const QSize &, QImage &) override { return false; } private: QScopedPointer<RenderWidgetHostViewQtDelegate> m_realDelegate; 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 2753f5d3d..45e87477f 100644 --- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp +++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp @@ -183,16 +183,15 @@ RenderWidgetHostViewQtDelegateWidget::~RenderWidgetHostViewQtDelegateWidget() void RenderWidgetHostViewQtDelegateWidget::connectRemoveParentBeforeParentDelete() { - if (QWidget *parent = parentWidget()) - connect(parent, &QObject::destroyed, - this, &RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete); -} - -void RenderWidgetHostViewQtDelegateWidget::disconnectRemoveParentBeforeParentDelete() -{ - if (QWidget *parent = parentWidget()) - disconnect(parent, &QObject::destroyed, - this, &RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete); + disconnect(m_parentDestroyedConnection); + + if (QWidget *parent = parentWidget()) { + m_parentDestroyedConnection = connect(parent, &QObject::destroyed, + this, + &RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete); + } else { + m_parentDestroyedConnection = QMetaObject::Connection(); + } } void RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete() @@ -417,15 +416,21 @@ void RenderWidgetHostViewQtDelegateWidget::hideEvent(QHideEvent *event) m_client->notifyHidden(); } +bool RenderWidgetHostViewQtDelegateWidget::copySurface(const QRect &rect, const QSize &size, QImage &image) +{ + QPixmap pixmap = rect.isEmpty() ? QQuickWidget::grab(QQuickWidget::rect()) : QQuickWidget::grab(rect); + if (pixmap.isNull()) + return false; + image = pixmap.toImage().scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + return true; +} + bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event) { bool handled = false; // Track parent to make sure we don't get deleted. switch (event->type()) { - case QEvent::ParentAboutToChange: - disconnectRemoveParentBeforeParentDelete(); - break; case QEvent::ParentChange: connectRemoveParentBeforeParentDelete(); break; 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 74c9e3413..e23f13d86 100644 --- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h +++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h @@ -88,6 +88,7 @@ public: void inputMethodStateChanged(bool editorVisible, bool passwordInput) override; void setInputMethodHints(Qt::InputMethodHints) override; void setClearColor(const QColor &color) override; + bool copySurface(const QRect &, const QSize &, QImage &) override; protected: bool event(QEvent *event) override; @@ -101,7 +102,6 @@ protected: private slots: void onWindowPosChanged(); void connectRemoveParentBeforeParentDelete(); - void disconnectRemoveParentBeforeParentDelete(); void removeParentBeforeParentDelete(); private: @@ -115,6 +115,7 @@ private: QPoint m_lastGlobalPos; QList<QMetaObject::Connection> m_windowConnections; QWebEnginePage *m_page = nullptr; + QMetaObject::Connection m_parentDestroyedConnection; }; } // namespace QtWebEngineCore diff --git a/tests/auto/quick/qmltests/data/directoryupload.html b/tests/auto/quick/qmltests/data/directoryupload.html index 6a6e4580c..adc408ebb 100644 --- a/tests/auto/quick/qmltests/data/directoryupload.html +++ b/tests/auto/quick/qmltests/data/directoryupload.html @@ -1,9 +1,10 @@ <html> <head> -<meta name="viewport" initial-scale=1"> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title> Directory Upload </title> <script src = "./titleupdate.js"> </script> +</head> <body> <input type="file" id="upfile" webkitdirectory="" directory="" onchange="updateTitle()"> diff --git a/tests/auto/quick/qmltests/data/favicon.html b/tests/auto/quick/qmltests/data/favicon.html index 7a81194e4..e1b84a9cc 100644 --- a/tests/auto/quick/qmltests/data/favicon.html +++ b/tests/auto/quick/qmltests/data/favicon.html @@ -1,7 +1,7 @@ <html> <head> -</head> <link type="image/png" href="icons/favicon.png" sizes="48x48" rel="icon" /> +</head> <body> <p>It's expected that you see a favicon displayed for this page when you open it as a local file.</p> <p>The favicon looks like this:</p> diff --git a/tests/auto/quick/qmltests/data/multifileupload.html b/tests/auto/quick/qmltests/data/multifileupload.html index cc87d8f41..1f788a377 100644 --- a/tests/auto/quick/qmltests/data/multifileupload.html +++ b/tests/auto/quick/qmltests/data/multifileupload.html @@ -1,9 +1,10 @@ <html> <head> -<meta name="viewport" initial-scale=1"> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title> Mutli-file Upload </title> <script src = "./titleupdate.js"> </script> +</head> <body> <input type="file" name="file" id="upfile" onchange="updateTitle()" multiple/> diff --git a/tests/auto/quick/qmltests/data/singlefileupload.html b/tests/auto/quick/qmltests/data/singlefileupload.html index 8469aa128..6cfef7ade 100644 --- a/tests/auto/quick/qmltests/data/singlefileupload.html +++ b/tests/auto/quick/qmltests/data/singlefileupload.html @@ -1,9 +1,10 @@ <html> <head> -<meta name="viewport" initial-scale=1"> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title> Single File Upload </title> <script src = "./titleupdate.js"> </script> +</head> <body> <input type="file" name="file" id="upfile" onchange="updateTitle()"/> diff --git a/tests/auto/quick/qmltests/data/test4.html b/tests/auto/quick/qmltests/data/test4.html index 142b53668..afda71bc5 100644 --- a/tests/auto/quick/qmltests/data/test4.html +++ b/tests/auto/quick/qmltests/data/test4.html @@ -12,7 +12,7 @@ <meta name="viewport" content="initial-scale=2.0"/> </head> <body> - <button onclick="scrollWin()", id="scroll">Click me to scroll!</button><br><br> + <button onclick="scrollWin()" id="scroll">Click me to scroll!</button><br><br> <script> window.onload = function() { diff --git a/tests/auto/widgets/printing/tst_printing.cpp b/tests/auto/widgets/printing/tst_printing.cpp index 2fd12b8ec..380fb65ff 100644 --- a/tests/auto/widgets/printing/tst_printing.cpp +++ b/tests/auto/widgets/printing/tst_printing.cpp @@ -44,7 +44,7 @@ class tst_Printing : public QObject private slots: void printToPdfBasic(); void printRequest(); -#if QT_CONFIG(webengine_poppler_cpp) +#if QT_CONFIG(webengine_poppler_cpp) && defined(Q_OS_LINUX) && defined(__GLIBCXX__) void printToPdfPoppler(); #endif }; @@ -108,7 +108,7 @@ void tst_Printing::printRequest() QVERIFY(data.length() > 0); } -#if QT_CONFIG(webengine_poppler_cpp) +#if QT_CONFIG(webengine_poppler_cpp) && defined(Q_OS_LINUX) && defined(__GLIBCXX__) void tst_Printing::printToPdfPoppler() { // check if generated pdf is correct by searching for a know string on the page diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index 92e281873..a0f8f11d2 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -191,6 +191,7 @@ private Q_SLOTS: void visibilityState(); void jsKeyboardEvent(); void deletePage(); + void closeOpenerTab(); }; // This will be called before the first test function is executed. @@ -2905,5 +2906,41 @@ void tst_QWebEngineView::deletePage() QTRY_VERIFY(spy.count()); } +class TestView : public QWebEngineView { + Q_OBJECT +public: + TestView(QWidget *parent = nullptr) : QWebEngineView(parent) + { + } + + QWebEngineView *createWindow(QWebEnginePage::WebWindowType) override + { + TestView *view = new TestView(parentWidget()); + createdWindows.append(view); + return view; + } + QList<TestView *> createdWindows; +}; + +void tst_QWebEngineView::closeOpenerTab() +{ + QWidget rootWidget; + rootWidget.resize(600, 400); + auto *testView = new TestView(&rootWidget); + testView->settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true); + QSignalSpy loadFinishedSpy(testView, SIGNAL(loadFinished(bool))); + testView->setUrl(QStringLiteral("about:blank")); + QTRY_VERIFY(loadFinishedSpy.count()); + testView->page()->runJavaScript(QStringLiteral("window.open('about:blank','_blank')")); + QTRY_COMPARE(testView->createdWindows.size(), 1); + auto *newView = testView->createdWindows.at(0); + newView->show(); + rootWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(newView)); + QVERIFY(newView->focusProxy()->isVisible()); + delete testView; + QVERIFY(newView->focusProxy()->isVisible()); +} + QTEST_MAIN(tst_QWebEngineView) #include "tst_qwebengineview.moc" |