diff options
author | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2024-10-07 17:38:05 +0300 |
---|---|---|
committer | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2024-10-07 17:44:32 +0300 |
commit | 183d0101f41fd5a1007708a9416d1f12db31c1cb (patch) | |
tree | 969a5e91aef3b4c6805331e56c24fa6be8738f6b | |
parent | 17e9f29577ea6573c7c348083ff510ee60c7e8cc (diff) | |
parent | 13381ca9e80578d038835c8a4dc609d75dfdec4c (diff) |
Merge tag 'v6.2.10-lts' into tqtc/lts-6.2-opensourcev6.2.10-lts-lgpl6.2.10
Qt 6.2.10-lts release
Conflicts solved:
CHROMIUM_VERSION
dependencies.yaml
src/core/web_engine_context.cpp
Change-Id: Ia54316ba0df3488d8e13c8f14fead1d90099519b
97 files changed, 726 insertions, 212 deletions
diff --git a/.cmake.conf b/.cmake.conf index bb0731ca8..d9b3c415c 100644 --- a/.cmake.conf +++ b/.cmake.conf @@ -1,3 +1,3 @@ -set(QT_REPO_MODULE_VERSION "6.2.9") +set(QT_REPO_MODULE_VERSION "6.2.10") set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "") set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_WEBENGINE "3.19") diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION index a024b4f70..ea03ba173 100644 --- a/CHROMIUM_VERSION +++ b/CHROMIUM_VERSION @@ -1,3 +1,3 @@ Based on Chromium version: 108.0.5359.181 -Patched with security patches up to Chromium version: 114.0.5735.133 +Patched with security patches up to Chromium version: 117.0.5938.63 diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake index f3c836432..73a06d59f 100644 --- a/cmake/Functions.cmake +++ b/cmake/Functions.cmake @@ -1245,6 +1245,9 @@ function(add_gn_command) ${arg_BUILDDIR}/${targetConfigFileName} ) add_dependencies(run_${arg_MODULE}_GnDone runGn_${arg_GN_TARGET}) + if(TARGET thirdparty_sync_headers) + add_dependencies(runGn_${arg_GN_TARGET} thirdparty_sync_headers) + endif() create_gn_target_config(${arg_GN_TARGET} ${arg_BUILDDIR}/${targetConfigFileName}) endfunction() diff --git a/config.tests/hostcompiler/hostcompiler.pro b/config.tests/hostcompiler/hostcompiler.pro deleted file mode 100644 index 5a80246ab..000000000 --- a/config.tests/hostcompiler/hostcompiler.pro +++ /dev/null @@ -1,9 +0,0 @@ -option(host_build) - -gcc:equals(QT_ARCH, "x86_64"):contains(QT_TARGET_ARCH, "arm"):!contains(QT_TARGET_ARCH, "arm64") { - QMAKE_CXXFLAGS += -m32 - QMAKE_LFLAGS += -m32 -} - -SOURCES = main.cpp - diff --git a/configure.cmake b/configure.cmake index 835017d5f..579125d04 100644 --- a/configure.cmake +++ b/configure.cmake @@ -574,11 +574,6 @@ ${xcbErrorMessage}" ) add_check_for_support( MODULES QtWebEngine QtPdf - CONDITION NOT WIN32 OR TEST_winversion - MESSAGE "Build requires Visual Studio 2019 or higher." -) -add_check_for_support( - MODULES QtWebEngine QtPdf CONDITION (LINUX AND CMAKE_CXX_COMPILER_ID STREQUAL GNU) OR (LINUX AND CMAKE_CXX_COMPILER_ID STREQUAL Clang) OR @@ -590,7 +585,6 @@ add_check_for_support( (ANDROID AND CMAKE_CXX_COMPILER_ID STREQUAL Clang) MESSAGE "${CMAKE_CXX_COMPILER_ID} compiler is not supported." ) - if(WIN32) if(CMAKE_CXX_COMPILER_ID STREQUAL MSVC) add_check_for_support( @@ -609,6 +603,11 @@ if(WIN32) MESSAGE "Build requires Windows 10 SDK at least version 10.0.20348.0" ) endif() +add_check_for_support( + MODULES QtWebEngine QtPdf + CONDITION NOT MSVC OR TEST_winversion + MESSAGE "Build requires Visual Studio 2019 or higher." +) #### Summary diff --git a/dependencies.yaml b/dependencies.yaml index bef830f8c..4013c6f19 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -1,13 +1,13 @@ dependencies: ../tqtc-qtdeclarative: - ref: b078003a3c81f1438dcaf932371d564003c99395 + ref: 9886ff37350f661aad5b8bfaf2776e8429f208a7 required: true ../tqtc-qtpositioning: - ref: 55581fd47ed2b5c8d4b3069f4b2fe1b2623e48d9 + ref: 5fd06158e68b3e6a3c557c011cd3e207d624186a required: false ../tqtc-qttools: - ref: ab1adda6499b84318eb769799e0cd402ffacfbda + ref: b55d00194d05ad065599e4ddb174eadc15310196 required: false ../tqtc-qtwebchannel: - ref: 8d4fbbf8608c9205bdeea2427486981d05f9153e + ref: f220057c327378841b3b08d3194626dc005a6a47 required: false diff --git a/examples/pdf/multipage/doc/src/multipage.qdoc b/examples/pdf/multipage/doc/src/multipage.qdoc index b4963c508..b9fec15a9 100644 --- a/examples/pdf/multipage/doc/src/multipage.qdoc +++ b/examples/pdf/multipage/doc/src/multipage.qdoc @@ -5,6 +5,7 @@ \example multipage \meta installpath pdf \ingroup qtpdf-examples + \examplecategory {Graphics & Multimedia} \title PDF Multipage Viewer Example \brief A Qt Quick PDF viewer that allows scrolling through the pages. diff --git a/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc b/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc index e585a84ef..0c9fa06a9 100644 --- a/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc +++ b/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc @@ -5,6 +5,7 @@ \example pdfviewer \meta installpath pdfwidgets \ingroup qtpdf-examples + \examplecategory {Graphics & Multimedia} \title PDF Viewer Widget Example \brief A widget-based PDF viewer that allows scrolling through the pages. diff --git a/examples/webenginequick/lifecycle/doc/src/lifecycle.qdoc b/examples/webenginequick/lifecycle/doc/src/lifecycle.qdoc index 4d997b1c4..1580da26d 100644 --- a/examples/webenginequick/lifecycle/doc/src/lifecycle.qdoc +++ b/examples/webenginequick/lifecycle/doc/src/lifecycle.qdoc @@ -6,6 +6,7 @@ \title WebEngine Lifecycle Example \ingroup webengine-examples \brief Freezes and discards background tabs to reduce CPU and memory usage. + \examplecategory {Web Technologies} \image lifecycle.png diff --git a/examples/webenginequick/quicknanobrowser/CMakeLists.txt b/examples/webenginequick/quicknanobrowser/CMakeLists.txt index ac41569aa..b2736e030 100644 --- a/examples/webenginequick/quicknanobrowser/CMakeLists.txt +++ b/examples/webenginequick/quicknanobrowser/CMakeLists.txt @@ -22,6 +22,7 @@ qt_add_executable(quicknanobrowser set_target_properties(quicknanobrowser PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE + MACOSX_BUNDLE_GUI_IDENTIFIER "io.qt.examples.webenginequick.quicknanobrowser" ) target_link_libraries(quicknanobrowser PUBLIC @@ -77,6 +78,18 @@ if(TARGET Qt::Widgets) ) endif() +if (APPLE) + set_target_properties(quicknanobrowser PROPERTIES + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.cmake.macos.plist" + ) + + if (NOT CMAKE_GENERATOR STREQUAL "Xcode") + # Need to sign application for location permissions to work + add_custom_command(TARGET quicknanobrowser + POST_BUILD COMMAND codesign -s - quicknanobrowser.app) + endif() +endif() + install(TARGETS quicknanobrowser RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/webenginequick/quicknanobrowser/Info.cmake.macos.plist b/examples/webenginequick/quicknanobrowser/Info.cmake.macos.plist new file mode 100644 index 000000000..cb967fc90 --- /dev/null +++ b/examples/webenginequick/quicknanobrowser/Info.cmake.macos.plist @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleName</key> + <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> + <key>CFBundleIdentifier</key> + <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> + <key>CFBundleExecutable</key> + <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> + <key>CFBundleVersion</key> + <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> + <key>CFBundleShortVersionString</key> + <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> + <key>LSMinimumSystemVersion</key> + <string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string> + <key>NSHumanReadableCopyright</key> + <string>${MACOSX_BUNDLE_COPYRIGHT}</string> + <key>CFBundleIconFile</key> + <string>${MACOSX_BUNDLE_ICON_FILE}</string> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>NSSupportsAutomaticGraphicsSwitching</key> + <true/> + <key>NSLocationUsageDescription</key> + <string>Quick Nano Browser would like to give web sites access to your location for demo purposes.</string> +</dict> +</plist> diff --git a/examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc b/examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc index ee94e0fd7..027a1f29a 100644 --- a/examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc +++ b/examples/webenginequick/quicknanobrowser/doc/src/quicknanobrowser.qdoc @@ -8,6 +8,8 @@ \brief A web browser implemented using the WebEngineView QML type. \image quicknanobrowser-demo.jpg + \examplecategory {Application Examples} + \examplecategory {Web Technologies} \e {Quick Nano Browser} demonstrates how to use the \l{Qt WebEngine QML Types} {Qt WebEngine QML types} to develop a small web browser application that consists of a browser diff --git a/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc b/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc index dc0383357..ae91affe5 100644 --- a/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc +++ b/examples/webenginewidgets/contentmanipulation/doc/src/contentmanipulation.qdoc @@ -3,6 +3,7 @@ /*! \example webenginewidgets/contentmanipulation + \examplecategory {Web Technologies} \title WebEngine Content Manipulation Example \ingroup webengine-widgetexamples \brief Demonstrates how to load and manipulate web content. diff --git a/examples/webenginewidgets/cookiebrowser/doc/src/cookiebrowser.qdoc b/examples/webenginewidgets/cookiebrowser/doc/src/cookiebrowser.qdoc index fe6d1b046..adc302779 100644 --- a/examples/webenginewidgets/cookiebrowser/doc/src/cookiebrowser.qdoc +++ b/examples/webenginewidgets/cookiebrowser/doc/src/cookiebrowser.qdoc @@ -3,6 +3,7 @@ /*! \example webenginewidgets/cookiebrowser + \examplecategory {Web Technologies} \title WebEngine Cookie Browser Example \ingroup webengine-widgetexamples \brief A cookie browser based on \QWE Widgets. diff --git a/examples/webenginewidgets/html2pdf/doc/src/html2pdf.qdoc b/examples/webenginewidgets/html2pdf/doc/src/html2pdf.qdoc index ba05c4e2b..7199a812c 100644 --- a/examples/webenginewidgets/html2pdf/doc/src/html2pdf.qdoc +++ b/examples/webenginewidgets/html2pdf/doc/src/html2pdf.qdoc @@ -3,6 +3,7 @@ /*! \example webenginewidgets/html2pdf + \examplecategory {Web Technologies} \title WebEngine Widgets Html2Pdf Example \ingroup webengine-widgetexamples \brief Converts web pages to PDF documents using \QWE. diff --git a/examples/webenginewidgets/maps/CMakeLists.txt b/examples/webenginewidgets/maps/CMakeLists.txt index f6e6b94ea..7f3f6d9ed 100644 --- a/examples/webenginewidgets/maps/CMakeLists.txt +++ b/examples/webenginewidgets/maps/CMakeLists.txt @@ -22,6 +22,7 @@ qt_add_executable(maps set_target_properties(maps PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE + MACOSX_BUNDLE_GUI_IDENTIFIER "io.qt.examples.webenginewidgets.maps" ) target_link_libraries(maps PUBLIC @@ -30,6 +31,19 @@ target_link_libraries(maps PUBLIC Qt::WebEngineWidgets ) +if (APPLE) + set_target_properties(maps PROPERTIES + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.cmake.macos.plist" + ) + + if (NOT CMAKE_GENERATOR STREQUAL "Xcode") + # Need to sign application for location permissions to work + add_custom_command(TARGET maps + POST_BUILD COMMAND codesign -s - maps.app) + endif() +endif() + + install(TARGETS maps RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/webenginewidgets/maps/Info.cmake.macos.plist b/examples/webenginewidgets/maps/Info.cmake.macos.plist new file mode 100644 index 000000000..56104a7d9 --- /dev/null +++ b/examples/webenginewidgets/maps/Info.cmake.macos.plist @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleName</key> + <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> + <key>CFBundleIdentifier</key> + <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> + <key>CFBundleExecutable</key> + <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> + <key>CFBundleVersion</key> + <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> + <key>CFBundleShortVersionString</key> + <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> + <key>LSMinimumSystemVersion</key> + <string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string> + <key>NSHumanReadableCopyright</key> + <string>${MACOSX_BUNDLE_COPYRIGHT}</string> + <key>CFBundleIconFile</key> + <string>${MACOSX_BUNDLE_ICON_FILE}</string> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>NSSupportsAutomaticGraphicsSwitching</key> + <true/> + <key>NSLocationUsageDescription</key> + <string>The maps demo would like to access your location for demo purposes.</string> +</dict> +</plist> diff --git a/examples/webenginewidgets/maps/doc/src/maps.qdoc b/examples/webenginewidgets/maps/doc/src/maps.qdoc index ad727e165..0175f8b65 100644 --- a/examples/webenginewidgets/maps/doc/src/maps.qdoc +++ b/examples/webenginewidgets/maps/doc/src/maps.qdoc @@ -3,6 +3,7 @@ /*! \example webenginewidgets/maps + \examplecategory {Web Technologies} \title WebEngine Widgets Maps Example \ingroup webengine-widgetexamples \brief Demonstrates how to handle geolocation requests. diff --git a/examples/webenginewidgets/notifications/doc/src/notifications.qdoc b/examples/webenginewidgets/notifications/doc/src/notifications.qdoc index fd3ffa482..f4fe1818f 100644 --- a/examples/webenginewidgets/notifications/doc/src/notifications.qdoc +++ b/examples/webenginewidgets/notifications/doc/src/notifications.qdoc @@ -3,6 +3,7 @@ /*! \example webenginewidgets/notifications + \examplecategory {Web Technologies} \title WebEngine Notifications Example \ingroup webengine-widgetexamples \brief Demonstrates how to pass HTML5 web notifications to users. diff --git a/examples/webenginewidgets/printme/doc/src/printme.qdoc b/examples/webenginewidgets/printme/doc/src/printme.qdoc index 76449f92e..cac69aa41 100644 --- a/examples/webenginewidgets/printme/doc/src/printme.qdoc +++ b/examples/webenginewidgets/printme/doc/src/printme.qdoc @@ -2,7 +2,8 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! - \example webenginewidgets/printme + \example webenginewidgets/printme + \examplecategory {Web Technologies} \title WebEngine Widgets PrintMe Example \ingroup webengine-widgetexamples \brief Demonstrates how to print web pages using Qt WebEngine Widgets. diff --git a/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qdoc b/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qdoc index 2f234c1e0..05ccf3e8b 100644 --- a/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qdoc +++ b/examples/webenginewidgets/push-notifications/doc/src/push-notifications.qdoc @@ -4,6 +4,7 @@ /*! \example webenginewidgets/push-notifications +\examplecategory {Web Technologies} \title WebEngine Push Notifications Example \ingroup webengine-widgetexamples \brief Demonstrates how to subscribe to and unsubscribe from push notifications. diff --git a/examples/webenginewidgets/recipebrowser/doc/src/recipebrowser.qdoc b/examples/webenginewidgets/recipebrowser/doc/src/recipebrowser.qdoc index dd701f1f2..0400fcecc 100644 --- a/examples/webenginewidgets/recipebrowser/doc/src/recipebrowser.qdoc +++ b/examples/webenginewidgets/recipebrowser/doc/src/recipebrowser.qdoc @@ -4,11 +4,11 @@ /*! \example webenginewidgets/recipebrowser \title Recipe Browser - \examplecategory {Application Examples} \meta tag {widgets, webengine, webchannel, webenginescript} \ingroup webengine-widgetexamples \brief Injecting custom stylsheets into web pages and providing a rich text preview tool for a custom markup language. + \examplecategory {Web Technologies} \image recipebrowser.webp diff --git a/examples/webenginewidgets/recipebrowser/mainwindow.cpp b/examples/webenginewidgets/recipebrowser/mainwindow.cpp index 7288fe4ce..79cd3bb6b 100644 --- a/examples/webenginewidgets/recipebrowser/mainwindow.cpp +++ b/examples/webenginewidgets/recipebrowser/mainwindow.cpp @@ -122,8 +122,7 @@ void MainWindow::loadDefaultStyleSheets() settings.beginGroup("styleSheets"); for (auto it = defaultStyleSheets.constBegin(); it != defaultStyleSheets.constEnd(); ++it) { - settings.setValue(it.key(), QVariant::fromValue(qMakePair(it.value(), true))); - insertStyleSheet(it.key(), it.value(), false); + settings.setValue(it.key(), QVariant::fromValue(qMakePair(it.value(), false))); } settings.endGroup(); diff --git a/examples/webenginewidgets/simplebrowser/CMakeLists.txt b/examples/webenginewidgets/simplebrowser/CMakeLists.txt index 2dd4fd57a..75f2e37da 100644 --- a/examples/webenginewidgets/simplebrowser/CMakeLists.txt +++ b/examples/webenginewidgets/simplebrowser/CMakeLists.txt @@ -32,6 +32,7 @@ qt_add_executable(simplebrowser set_target_properties(simplebrowser PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE + MACOSX_BUNDLE_GUI_IDENTIFIER "io.qt.examples.webenginewidgets.simplebrowser" ) target_link_libraries(simplebrowser PUBLIC @@ -75,6 +76,19 @@ qt_add_resources(simplebrowser "simplebrowser1" ${simplebrowser1_resource_files} ) +if (APPLE) + set_target_properties(simplebrowser PROPERTIES + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.cmake.macos.plist" + ) + + if (NOT CMAKE_GENERATOR STREQUAL "Xcode") + # Need to sign application for location permissions to work + add_custom_command(TARGET simplebrowser + POST_BUILD COMMAND codesign -s - simplebrowser.app) + endif() +endif() + + install(TARGETS simplebrowser RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/webenginewidgets/simplebrowser/Info.cmake.macos.plist b/examples/webenginewidgets/simplebrowser/Info.cmake.macos.plist new file mode 100644 index 000000000..76f747719 --- /dev/null +++ b/examples/webenginewidgets/simplebrowser/Info.cmake.macos.plist @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleName</key> + <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> + <key>CFBundleIdentifier</key> + <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> + <key>CFBundleExecutable</key> + <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> + <key>CFBundleVersion</key> + <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> + <key>CFBundleShortVersionString</key> + <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> + <key>LSMinimumSystemVersion</key> + <string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string> + <key>NSHumanReadableCopyright</key> + <string>${MACOSX_BUNDLE_COPYRIGHT}</string> + <key>CFBundleIconFile</key> + <string>${MACOSX_BUNDLE_ICON_FILE}</string> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>NSSupportsAutomaticGraphicsSwitching</key> + <true/> + <key>NSLocationUsageDescription</key> + <string>Simple Browser would like to give web sites access to your location for demo purposes.</string> +</dict> +</plist> diff --git a/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc index f45b362df..7f8e386c0 100644 --- a/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc +++ b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc @@ -6,6 +6,7 @@ \title WebEngine Widgets Simple Browser Example \ingroup webengine-widgetexamples \brief A simple browser based on \QWE Widgets. + \examplecategory {Web Technologies} \image simplebrowser.png diff --git a/examples/webenginewidgets/spellchecker/doc/src/spellchecker.qdoc b/examples/webenginewidgets/spellchecker/doc/src/spellchecker.qdoc index 85b1b950c..1d9d7b73c 100644 --- a/examples/webenginewidgets/spellchecker/doc/src/spellchecker.qdoc +++ b/examples/webenginewidgets/spellchecker/doc/src/spellchecker.qdoc @@ -6,6 +6,7 @@ \title WebEngine Widgets Spellchecker Example \ingroup webengine-widgetexamples \brief Integrates a spellchecker into a simple HTML form. + \examplecategory {Web Technologies} \image spellchecker-example.png diff --git a/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc b/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc index 9dcd5c0ff..931f08558 100644 --- a/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc +++ b/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc @@ -3,6 +3,7 @@ /*! \example webenginewidgets/videoplayer + \examplecategory {Web Technologies} \title WebEngine Widgets Video Player Example \ingroup webengine-widgetexamples \brief Displays full screen video using \l QWebEngineView. diff --git a/src/3rdparty b/src/3rdparty -Subproject 08741ef38efb3754c1f244ea175d5a4c98b69fa +Subproject ef090c47d08c734ae2b3c1db508982aca0f3ee1 diff --git a/src/core/api/CMakeLists.txt b/src/core/api/CMakeLists.txt index 922adfd8c..94ed3c852 100644 --- a/src/core/api/CMakeLists.txt +++ b/src/core/api/CMakeLists.txt @@ -95,7 +95,7 @@ add_code_attributions_target( BUILDDIR ${buildDir}/${config}/${arch} ) add_dependencies(generate_chromium_attributions run_core_GnDone) -add_dependencies(docs generate_chromium_attributions) +add_dependencies(prepare_docs_WebEngineCore generate_chromium_attributions) ## # WEBENGINECORE RESOURCES diff --git a/src/core/api/qtwebenginecoreglobal.cpp b/src/core/api/qtwebenginecoreglobal.cpp index 2736e1a33..7029cebbd 100644 --- a/src/core/api/qtwebenginecoreglobal.cpp +++ b/src/core/api/qtwebenginecoreglobal.cpp @@ -212,7 +212,12 @@ static void initialize() // QCoreApplication is not yet instantiated, ensuring the call will be deferred qAddPreRoutine(QtWebEngineCore::initialize); auto api = QQuickWindow::graphicsApi(); - if (api != QSGRendererInterface::OpenGL && api != QSGRendererInterface::Vulkan) + if (api != QSGRendererInterface::OpenGL +#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0) + && api != QSGRendererInterface::Vulkan + && api != QSGRendererInterface::Metal && api != QSGRendererInterface::Direct3D11 +#endif + ) QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL); #endif // QT_CONFIG(opengl) } diff --git a/src/core/api/qwebenginefilesystemaccessrequest.cpp b/src/core/api/qwebenginefilesystemaccessrequest.cpp index 6527e1766..3f901b671 100644 --- a/src/core/api/qwebenginefilesystemaccessrequest.cpp +++ b/src/core/api/qwebenginefilesystemaccessrequest.cpp @@ -27,6 +27,25 @@ QT_BEGIN_NAMESPACE either call accept() or reject(). */ +/*! + \enum QWebEngineFileSystemAccessRequest::AccessFlag + + This enum describes the type of the requested access: read, write or both. The options + can be OR-ed together from the following list: + + \value Read + \value Write +*/ + +/*! + \enum QWebEngineFileSystemAccessRequest::HandleType + + This enum describes the type of the requested file system entry. + + \value File + \value Directory +*/ + QWebEngineFileSystemAccessRequest::QWebEngineFileSystemAccessRequest( const QWebEngineFileSystemAccessRequest &other) = default; QWebEngineFileSystemAccessRequest &QWebEngineFileSystemAccessRequest::operator=( diff --git a/src/core/api/qwebenginehistory.cpp b/src/core/api/qwebenginehistory.cpp index b70c0b73d..5d2fc8e9e 100644 --- a/src/core/api/qwebenginehistory.cpp +++ b/src/core/api/qwebenginehistory.cpp @@ -242,13 +242,6 @@ QWebEngineHistory::QWebEngineHistory(QWebEngineHistoryPrivate *d) : d_ptr(d) { } QWebEngineHistory::~QWebEngineHistory() { } -/*! - \qmlmethod void WebEngineHistory::clear() - \since QtWebEngine 1.11 - - Clears the history. -*/ - void QWebEngineHistory::clear() { Q_D(const QWebEngineHistory); diff --git a/src/core/api/qwebenginemessagepumpscheduler.cpp b/src/core/api/qwebenginemessagepumpscheduler.cpp index 62244c787..a435e2c0c 100644 --- a/src/core/api/qwebenginemessagepumpscheduler.cpp +++ b/src/core/api/qwebenginemessagepumpscheduler.cpp @@ -11,9 +11,14 @@ QWebEngineMessagePumpScheduler::QWebEngineMessagePumpScheduler(std::function<voi : m_callback(std::move(callback)) {} -void QWebEngineMessagePumpScheduler::scheduleWork() +void QWebEngineMessagePumpScheduler::scheduleImmediateWork() { - QCoreApplication::postEvent(this, new QTimerEvent(0)); + QCoreApplication::postEvent(this, new QTimerEvent(0), Qt::NormalEventPriority); +} + +void QWebEngineMessagePumpScheduler::scheduleIdleWork() +{ + QCoreApplication::postEvent(this, new QTimerEvent(0), Qt::LowEventPriority); } void QWebEngineMessagePumpScheduler::scheduleDelayedWork(int delay) diff --git a/src/core/api/qwebenginemessagepumpscheduler_p.h b/src/core/api/qwebenginemessagepumpscheduler_p.h index 7e84b4190..4ec7ef125 100644 --- a/src/core/api/qwebenginemessagepumpscheduler_p.h +++ b/src/core/api/qwebenginemessagepumpscheduler_p.h @@ -28,7 +28,8 @@ class Q_WEBENGINECORE_PRIVATE_EXPORT QWebEngineMessagePumpScheduler : public QOb Q_OBJECT public: QWebEngineMessagePumpScheduler(std::function<void()> callback); - void scheduleWork(); + void scheduleImmediateWork(); + void scheduleIdleWork(); void scheduleDelayedWork(int delay); protected: diff --git a/src/core/api/qwebenginenavigationrequest.cpp b/src/core/api/qwebenginenavigationrequest.cpp index c14a7bf41..0a30f6472 100644 --- a/src/core/api/qwebenginenavigationrequest.cpp +++ b/src/core/api/qwebenginenavigationrequest.cpp @@ -89,7 +89,10 @@ void QWebEngineNavigationRequest::setAction(QWebEngineNavigationRequest::Navigat return; acceptRequest ? accept() : reject(); +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED emit actionChanged(); +QT_WARNING_POP } #endif /*! diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp index dff2418b5..78021248c 100644 --- a/src/core/api/qwebenginepage.cpp +++ b/src/core/api/qwebenginepage.cpp @@ -103,7 +103,9 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile) { memset(actions, 0, sizeof(actions)); +#if QT_DEPRECATED_SINCE(6, 5) qRegisterMetaType<QWebEngineQuotaRequest>(); +#endif qRegisterMetaType<QWebEngineRegisterProtocolHandlerRequest>(); qRegisterMetaType<QWebEngineFileSystemAccessRequest>(); qRegisterMetaType<QWebEngineFindTextResult>(); @@ -508,6 +510,15 @@ void QWebEnginePagePrivate::runRegisterProtocolHandlerRequest(QWebEngineRegister Q_EMIT q->registerProtocolHandlerRequested(request); } +/*! + \fn void QWebEnginePage::fileSystemAccessRequested(QWebEngineFileSystemAccessRequest request) + \since 6.4 + + This signal is emitted when the web page requests access to local files or directories. + + The request object \a request can be used to accept or reject the request. +*/ + void QWebEnginePagePrivate::runFileSystemAccessRequest(QWebEngineFileSystemAccessRequest request) { Q_Q(QWebEnginePage); @@ -1502,7 +1513,7 @@ void QWebEnginePagePrivate::contextMenuRequested(QWebEngineContextMenuRequest *d } /*! - \fn bool QWebEnginePage::navigationRequested(QWebEngineNavigationRequest &request) + \fn void QWebEnginePage::navigationRequested(QWebEngineNavigationRequest &request) \since 6.2 This signal is emitted on navigation together with the call the acceptNavigationRequest(). @@ -1643,6 +1654,17 @@ void QWebEnginePagePrivate::setToolTip(const QString &toolTipText) view->setToolTip(toolTipText); } +/*! + \fn void QWebEnginePage::printRequested() + \since 5.12 + + This signal is emitted when the JavaScript \c{window.print()} method is called or the user pressed the print + button of PDF viewer plugin. + Typically, the signal handler can simply call printToPdf(). + + \sa printToPdf() +*/ + void QWebEnginePagePrivate::printRequested() { Q_Q(QWebEnginePage); diff --git a/src/core/browser_accessibility_manager_qt.cpp b/src/core/browser_accessibility_manager_qt.cpp index 49a193b05..299eb7bb3 100644 --- a/src/core/browser_accessibility_manager_qt.cpp +++ b/src/core/browser_accessibility_manager_qt.cpp @@ -13,10 +13,6 @@ #include "render_widget_host_view_qt.h" // WebContentsAccessibilityQt #include "content/browser/accessibility/browser_accessibility.h" -#if QT_CONFIG(webengine_extensions) -#include "content/browser/renderer_host/render_frame_host_impl.h" -#include "content/public/browser/web_contents.h" -#endif // QT_CONFIG(webengine_extensions) #include "ui/accessibility/ax_enums.mojom.h" #include <QtGui/qaccessible.h> @@ -34,12 +30,10 @@ BrowserAccessibilityManager *BrowserAccessibilityManager::Create( QtWebEngineCore::WebContentsAccessibilityQt *access = nullptr; access = static_cast<QtWebEngineCore::WebContentsAccessibilityQt *>(delegate->AccessibilityGetWebContentsAccessibility()); -#if QT_CONFIG(webengine_extensions) - // Accessibility is not supported for guest views. + // Accessibility is not supported for guest views and child frames. if (!access) { return nullptr; } -#endif // QT_CONFIG(webengine_extensions) return new BrowserAccessibilityManagerQt(access, initialTree, delegate); #else diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp index d1cdd4b20..24c006dc5 100644 --- a/src/core/browser_accessibility_qt.cpp +++ b/src/core/browser_accessibility_qt.cpp @@ -25,10 +25,7 @@ public: BrowserAccessibilityQt(content::BrowserAccessibilityManager *manager, ui::AXNode *node); ~BrowserAccessibilityQt(); - QtWebEngineCore::BrowserAccessibilityInterface *interface() const { return m_interface; } - -private: - QtWebEngineCore::BrowserAccessibilityInterface *m_interface = nullptr; + QtWebEngineCore::BrowserAccessibilityInterface *interface = nullptr; }; class BrowserAccessibilityInterface @@ -41,6 +38,7 @@ class BrowserAccessibilityInterface { public: BrowserAccessibilityInterface(BrowserAccessibilityQt *chromiumInterface); + ~BrowserAccessibilityInterface() override; void destroy(); @@ -133,15 +131,17 @@ private: BrowserAccessibilityQt *q; }; -BrowserAccessibilityQt::BrowserAccessibilityQt(content::BrowserAccessibilityManager *manager, ui::AXNode *node) - : content::BrowserAccessibility(manager, node), - m_interface(new BrowserAccessibilityInterface(this)) +BrowserAccessibilityQt::BrowserAccessibilityQt(content::BrowserAccessibilityManager *manager, + ui::AXNode *node) + : content::BrowserAccessibility(manager, node) + , interface(new BrowserAccessibilityInterface(this)) { } BrowserAccessibilityQt::~BrowserAccessibilityQt() { - m_interface->destroy(); + if (interface) + interface->destroy(); } BrowserAccessibilityInterface::BrowserAccessibilityInterface(BrowserAccessibilityQt *chromiumInterface) @@ -157,6 +157,11 @@ BrowserAccessibilityInterface::BrowserAccessibilityInterface(BrowserAccessibilit m_id = QAccessible::registerAccessibleInterface(this); } +BrowserAccessibilityInterface::~BrowserAccessibilityInterface() +{ + q->interface = nullptr; +} + void BrowserAccessibilityInterface::destroy() { QAccessible::deleteAccessibleInterface(m_id); @@ -1140,12 +1145,12 @@ std::unique_ptr<BrowserAccessibility> BrowserAccessibility::Create(BrowserAccess QAccessibleInterface *toQAccessibleInterface(BrowserAccessibility *obj) { - return static_cast<QtWebEngineCore::BrowserAccessibilityQt *>(obj)->interface(); + return static_cast<QtWebEngineCore::BrowserAccessibilityQt *>(obj)->interface; } const QAccessibleInterface *toQAccessibleInterface(const BrowserAccessibility *obj) { - return static_cast<const QtWebEngineCore::BrowserAccessibilityQt *>(obj)->interface(); + return static_cast<const QtWebEngineCore::BrowserAccessibilityQt *>(obj)->interface; } } // namespace content diff --git a/src/core/browser_main_parts_qt.cpp b/src/core/browser_main_parts_qt.cpp index e58822c29..93522d239 100644 --- a/src/core/browser_main_parts_qt.cpp +++ b/src/core/browser_main_parts_qt.cpp @@ -50,6 +50,7 @@ #include "web_engine_context.h" #include "web_usb_detector_qt.h" +#include <QDeadlineTimer> #include <QtGui/qtgui-config.h> #include <QStandardPaths> @@ -120,7 +121,7 @@ public: { // NOTE: This method may called from any thread at any time. ensureDelegate(); - m_scheduler.scheduleWork(); + m_scheduler.scheduleImmediateWork(); } void ScheduleDelayedWork(const Delegate::NextWorkInfo &next_work_info) override @@ -193,13 +194,16 @@ private: { ScopedGLContextChecker glContextChecker; + QDeadlineTimer timer(std::chrono::milliseconds(2)); base::MessagePump::Delegate::NextWorkInfo more_work_info = m_delegate->DoWork(); + while (more_work_info.is_immediate() && !timer.hasExpired()) + more_work_info = m_delegate->DoWork(); if (more_work_info.is_immediate()) - return ScheduleWork(); + return m_scheduler.scheduleImmediateWork(); if (m_delegate->DoIdleWork()) - return ScheduleWork(); + return m_scheduler.scheduleIdleWork(); ScheduleDelayedWork(more_work_info.delayed_run_time); } diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp index 009235a72..fe56a5db1 100644 --- a/src/core/clipboard_qt.cpp +++ b/src/core/clipboard_qt.cpp @@ -27,6 +27,8 @@ #include <QImageWriter> #include <QMimeData> +#include <memory> + namespace QtWebEngineCore { static void registerMetaTypes() @@ -60,12 +62,12 @@ using namespace QtWebEngineCore; namespace { -QScopedPointer<QMimeData> uncommittedData; +std::unique_ptr<QMimeData> uncommittedData; QMimeData *getUncommittedData() { if (!uncommittedData) uncommittedData.reset(new QMimeData); - return uncommittedData.data(); + return uncommittedData.get(); } } // namespace @@ -104,7 +106,7 @@ void ClipboardQt::WritePortableAndPlatformRepresentations(ui::ClipboardBuffer ty // Commit the accumulated data. if (uncommittedData) - QGuiApplication::clipboard()->setMimeData(uncommittedData.take(), + QGuiApplication::clipboard()->setMimeData(uncommittedData.release(), type == ui::ClipboardBuffer::kCopyPaste ? QClipboard::Clipboard : QClipboard::Selection); diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp index fab8a5abb..3d7a157bd 100644 --- a/src/core/content_client_qt.cpp +++ b/src/core/content_client_qt.cpp @@ -61,7 +61,7 @@ static QString webenginePluginsPath() { // Look for plugins in /plugins/webengine or application dir. static bool initialized = false; - static QString potentialPluginsPath = QLibraryInfo::location(QLibraryInfo::PluginsPath) % QLatin1String("/webengine"); + static QString potentialPluginsPath = QLibraryInfo::path(QLibraryInfo::PluginsPath) % QLatin1String("/webengine"); if (!initialized) { initialized = true; if (!QFileInfo::exists(potentialPluginsPath)) @@ -105,7 +105,7 @@ static QString ppapiPluginsPath() { // Look for plugins in /plugins/ppapi or application dir. static bool initialized = false; - static QString potentialPluginsPath = QLibraryInfo::location(QLibraryInfo::PluginsPath) % QLatin1String("/ppapi"); + static QString potentialPluginsPath = QLibraryInfo::path(QLibraryInfo::PluginsPath) % QLatin1String("/ppapi"); if (!initialized) { initialized = true; if (!QFileInfo::exists(potentialPluginsPath)) diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp index 52e23399e..feaaaaa9a 100644 --- a/src/core/content_main_delegate_qt.cpp +++ b/src/core/content_main_delegate_qt.cpp @@ -14,7 +14,6 @@ #include "content/public/browser/browser_main_runner.h" #include "content/public/common/content_paths.h" #include "content/public/common/content_switches.h" -#include "media/gpu/buildflags.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/ui_base_paths.h" #include "ui/base/resource/resource_bundle.h" @@ -39,9 +38,6 @@ #include "ui/base/ui_base_switches.h" #endif -// must be included before vaapi_wrapper.h -#include <QtCore/qcoreapplication.h> - #if BUILDFLAG(IS_WIN) #include "media/gpu/windows/dxva_video_decode_accelerator_win.h" #include "media/gpu/windows/media_foundation_video_encode_accelerator_win.h" @@ -53,9 +49,7 @@ #include "media/gpu/mac/vt_video_decode_accelerator_mac.h" #endif -#if BUILDFLAG(USE_VAAPI) -#include "media/gpu/vaapi/vaapi_wrapper.h" -#endif +#include <QtCore/qcoreapplication.h> namespace content { ContentClient *GetContentClient(); @@ -171,21 +165,21 @@ void ContentMainDelegateQt::PreSandboxStartup() setlocale(LC_NUMERIC, "C"); #endif - // from gpu_main.cc: -#if BUILDFLAG(USE_VAAPI) - media::VaapiWrapper::PreSandboxInitialization(); -#endif + bool isBrowserProcess = !parsedCommandLine->HasSwitch(switches::kProcessType); + if (isBrowserProcess) { + // from gpu_main.cc: #if BUILDFLAG(IS_WIN) - media::DXVAVideoDecodeAccelerator::PreSandboxInitialization(); - media::MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization(); + media::DXVAVideoDecodeAccelerator::PreSandboxInitialization(); + media::MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization(); #endif #if BUILDFLAG(IS_MAC) - { - TRACE_EVENT0("gpu", "Initialize VideoToolbox"); - media::InitializeVideoToolbox(); - } + { + TRACE_EVENT0("gpu", "Initialize VideoToolbox"); + media::InitializeVideoToolbox(); + } #endif + } if (parsedCommandLine->HasSwitch(switches::kApplicationName)) { std::string appName = parsedCommandLine->GetSwitchValueASCII(switches::kApplicationName); diff --git a/src/core/devtools_frontend_qt.cpp b/src/core/devtools_frontend_qt.cpp index 731414db9..3fddd3410 100644 --- a/src/core/devtools_frontend_qt.cpp +++ b/src/core/devtools_frontend_qt.cpp @@ -62,7 +62,7 @@ DevToolsFrontendQt *DevToolsFrontendQt::Show(QSharedPointer<WebContentsAdapter> new DevToolsFrontendQt(frontendAdapter, inspectedContents); if (contents->GetURL() == GURL(GetFrontendURL())) { - contents->GetController().Reload(content::ReloadType::ORIGINAL_REQUEST_URL, false); + contents->GetController().LoadOriginalRequestURL(); } else { content::NavigationController::LoadURLParams loadParams((GURL(GetFrontendURL()))); loadParams.transition_type = ui::PageTransitionFromInt(ui::PAGE_TRANSITION_AUTO_TOPLEVEL @@ -162,7 +162,7 @@ void DevToolsFrontendQt::ActivateWindow() web_contents()->Focus(); } -void DevToolsFrontendQt::InspectElementCompleted() +void DevToolsFrontendQt::OnLoadCompleted() { m_bindings->CallClientMethod("DevToolsAPI", "setUseSoftMenu", base::Value(true)); } @@ -204,4 +204,9 @@ void DevToolsFrontendQt::InspectedContentsClosing() web_contents()->ClosePage(); } +void DevToolsFrontendQt::CloseWindow() +{ + web_contents()->Close(); +} + } // namespace QtWebEngineCore diff --git a/src/core/devtools_frontend_qt.h b/src/core/devtools_frontend_qt.h index 3b722c9ad..9b739033a 100644 --- a/src/core/devtools_frontend_qt.h +++ b/src/core/devtools_frontend_qt.h @@ -54,18 +54,18 @@ private: // DevToolsUIBindings::Delegate overrides void ActivateWindow() override; - void InspectElementCompleted() override; void SetEyeDropperActive(bool active) override; void OpenInNewTab(const std::string &url) override; void InspectedContentsClosing() override; + void OnLoadCompleted() override; - void CloseWindow() override{}; + void InspectElementCompleted() override{}; + void CloseWindow() override; void Inspect(scoped_refptr<content::DevToolsAgentHost>) override{}; void SetInspectedPageBounds(const gfx::Rect &) override{}; void SetIsDocked(bool) override{}; void SetWhitelistedShortcuts(const std::string &) override{}; void OpenNodeFrontend() override{}; - void OnLoadCompleted() override{}; void ReadyForTest() override{}; void ConnectionReady() override{}; void SetOpenNewWindowForPopups(bool) override{}; diff --git a/src/core/doc/about_credits_entry.tmpl b/src/core/doc/about_credits_entry.tmpl index aa94f2945..2bb9cff4e 100644 --- a/src/core/doc/about_credits_entry.tmpl +++ b/src/core/doc/about_credits_entry.tmpl @@ -1,6 +1,5 @@ /*! -\page qtwebengine-3rdparty-{{name-sanitized}}.html -\attribution +\page qtwebengine-3rdparty-{{name-sanitized}}.html attribution \ingroup qtwebengine-licensing \brief {{license-type}} \title {{name}} diff --git a/src/core/doc/snippets/qtwebenginecore_build_snippet.qdoc b/src/core/doc/snippets/qtwebenginecore_build_snippet.qdoc index ee22ea774..9a7370d62 100644 --- a/src/core/doc/snippets/qtwebenginecore_build_snippet.qdoc +++ b/src/core/doc/snippets/qtwebenginecore_build_snippet.qdoc @@ -7,5 +7,5 @@ QT += webenginecore //! [2] find_package(Qt6 REQUIRED COMPONENTS WebEngineCore) -target_link_libraries(target PRIVATE Qt::WebEngineCore) +target_link_libraries(target PRIVATE Qt6::WebEngineCore) //! [2] diff --git a/src/core/doc/src/qtwebengine-deploying.qdoc b/src/core/doc/src/qtwebengine-deploying.qdoc index 7504965e3..625570fee 100644 --- a/src/core/doc/src/qtwebengine-deploying.qdoc +++ b/src/core/doc/src/qtwebengine-deploying.qdoc @@ -4,6 +4,7 @@ /*! \page qtwebengine-deploying.html \title Deploying Qt WebEngine Applications + \ingroup explanations-webtechnologies The way to package and deploy applications varies between operating systems. For Windows and \macos, \l{The Windows Deployment Tool}{windeployqt} and diff --git a/src/core/doc/src/qtwebengine-features.qdoc b/src/core/doc/src/qtwebengine-features.qdoc index 3d6d0fea8..29e7b0f06 100644 --- a/src/core/doc/src/qtwebengine-features.qdoc +++ b/src/core/doc/src/qtwebengine-features.qdoc @@ -4,6 +4,7 @@ /*! \page qtwebengine-features.html \title Qt WebEngine Features + \ingroup explanations-webtechnologies \brief Summarizes \QWE features. @@ -304,6 +305,10 @@ {Location services}, \uicontrol {Let apps access your location} and \uicontrol {Let desktop apps access your location}. + \note On macOS add a description text explaining why use of the location is needed + using the \c NSLocationUsageDescription in your application's \c Info.plist file + and sign the application to trigger \c macos to ask the user for permission. + See \l{Qt Positioning} for a possible backend setup like the GPS or IP based positioning. Support for this feature was added in Qt 5.5.0. diff --git a/src/core/doc/src/qtwebengine-overview.qdoc b/src/core/doc/src/qtwebengine-overview.qdoc index b1e8ee3da..6eccc669e 100644 --- a/src/core/doc/src/qtwebengine-overview.qdoc +++ b/src/core/doc/src/qtwebengine-overview.qdoc @@ -4,6 +4,7 @@ /*! \page qtwebengine-overview.html \title Qt WebEngine Overview + \ingroup explanations-webtechnologies The \QWE module provides a web browser engine that makes it easy to embed content from the World Wide Web into your Qt application on platforms that do not have a native web engine. diff --git a/src/core/doc/src/qwebengine-licensing.qdoc b/src/core/doc/src/qwebengine-licensing.qdoc index 796a9664d..ed1c5f376 100644 --- a/src/core/doc/src/qwebengine-licensing.qdoc +++ b/src/core/doc/src/qwebengine-licensing.qdoc @@ -22,8 +22,7 @@ Third party licenses included in the sources are: */ /*! -\page qtwebengine-3rdparty-chromium-global.html -\attribution +\page qtwebengine-3rdparty-chromium-global.html attribution \ingroup qtwebengine-licensing \title Chromium License \brief BSD diff --git a/src/core/file_picker_controller.cpp b/src/core/file_picker_controller.cpp index 6ec7258b9..9b4521358 100644 --- a/src/core/file_picker_controller.cpp +++ b/src/core/file_picker_controller.cpp @@ -136,7 +136,7 @@ void FilePickerController::accepted(const QVariant &files) { QStringList stringList; - if (files.canConvert(QMetaType::QStringList)) { + if (files.canConvert(QMetaType{QMetaType::QStringList})) { stringList = files.toStringList(); } else if (files.canConvert<QList<QUrl> >()) { const QList<QUrl> urls = files.value<QList<QUrl>>(); diff --git a/src/core/net/proxy_config_service_qt.cpp b/src/core/net/proxy_config_service_qt.cpp index 70bcb59b4..fcce08550 100644 --- a/src/core/net/proxy_config_service_qt.cpp +++ b/src/core/net/proxy_config_service_qt.cpp @@ -16,14 +16,15 @@ net::ProxyServer ProxyConfigServiceQt::fromQNetworkProxy(const QNetworkProxy &qtProxy) { - net::HostPortPair hostPortPair(qtProxy.hostName().toStdString(), qtProxy.port()); + std::string host = qtProxy.hostName().toStdString(); + uint16_t port = qtProxy.port(); switch (qtProxy.type()) { case QNetworkProxy::Socks5Proxy: - return net::ProxyServer(net::ProxyServer::SCHEME_SOCKS5, hostPortPair); + return net::ProxyServer::FromSchemeHostAndPort(net::ProxyServer::SCHEME_SOCKS5, host, port); case QNetworkProxy::HttpProxy: case QNetworkProxy::HttpCachingProxy: case QNetworkProxy::FtpCachingProxy: - return net::ProxyServer(net::ProxyServer::SCHEME_HTTP, hostPortPair); + return net::ProxyServer::FromSchemeHostAndPort(net::ProxyServer::SCHEME_HTTP, host, port); case QNetworkProxy::NoProxy: case QNetworkProxy::DefaultProxy: return net::ProxyServer(net::ProxyServer::SCHEME_DIRECT, net::HostPortPair()); diff --git a/src/core/net/proxying_url_loader_factory_qt.cpp b/src/core/net/proxying_url_loader_factory_qt.cpp index 70ec61b34..2c61015e6 100644 --- a/src/core/net/proxying_url_loader_factory_qt.cpp +++ b/src/core/net/proxying_url_loader_factory_qt.cpp @@ -126,8 +126,6 @@ public: void PauseReadingBodyFromNet() override; void ResumeReadingBodyFromNet() override; - static inline void cleanup(QWebEngineUrlRequestInfo *info) { delete info; } - private: void InterceptOnUIThread(); void ContinueAfterIntercept(); @@ -169,7 +167,13 @@ private: const net::MutableNetworkTrafficAnnotationTag traffic_annotation_; - QScopedPointer<QWebEngineUrlRequestInfo, InterceptedRequest> request_info_; + struct RequestInfoDeleter + { + void operator()(QWebEngineUrlRequestInfo *ptr) const + { delete ptr; } + }; + + std::unique_ptr<QWebEngineUrlRequestInfo, RequestInfoDeleter> request_info_; mojo::Receiver<network::mojom::URLLoader> proxied_loader_receiver_; mojo::Remote<network::mojom::URLLoaderClient> target_client_; @@ -349,7 +353,7 @@ void InterceptedRequest::ContinueAfterIntercept() if (request_info_) { // cleanup in scope because of delete this and it's not needed else where after - decltype(request_info_) scoped_request_info(request_info_.take()); + const auto scoped_request_info = std::move(request_info_); QWebEngineUrlRequestInfoPrivate &info = *scoped_request_info->d_ptr; if (info.changed) { diff --git a/src/core/net/qrc_url_scheme_handler.cpp b/src/core/net/qrc_url_scheme_handler.cpp index ab66acac0..a8b4e4388 100644 --- a/src/core/net/qrc_url_scheme_handler.cpp +++ b/src/core/net/qrc_url_scheme_handler.cpp @@ -10,6 +10,8 @@ #include <QMimeDatabase> #include <QMimeType> +#include <memory> + namespace QtWebEngineCore { void QrcUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job) @@ -22,7 +24,7 @@ void QrcUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job) QUrl requestUrl = job->requestUrl(); QString requestPath = requestUrl.path(); - QScopedPointer<QFile> file(new QFile(':' + requestPath, job)); + auto file = std::make_unique<QFile>(':' + requestPath, job); if (!file->exists() || file->size() == 0) { qWarning("QResource '%s' not found or is empty", qUtf8Printable(requestPath)); job->fail(QWebEngineUrlRequestJob::UrlNotFound); @@ -32,9 +34,9 @@ void QrcUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *job) QMimeDatabase mimeDatabase; QMimeType mimeType = mimeDatabase.mimeTypeForFile(fileInfo); if (mimeType.name() == QStringLiteral("application/x-extension-html")) - job->reply("text/html", file.take()); + job->reply("text/html", file.release()); else - job->reply(mimeType.name().toUtf8(), file.take()); + job->reply(mimeType.name().toUtf8(), file.release()); } } // namespace QtWebEngineCore diff --git a/src/core/printing/print_view_manager_qt.cpp b/src/core/printing/print_view_manager_qt.cpp index 7d8a796f7..892c9e406 100644 --- a/src/core/printing/print_view_manager_qt.cpp +++ b/src/core/printing/print_view_manager_qt.cpp @@ -336,12 +336,23 @@ void PrintViewManagerQt::ShowScriptedPrintPreview(bool /*source_is_modifiable*/) // ignore for now } -void PrintViewManagerQt::RequestPrintPreview(printing::mojom::RequestPrintPreviewParamsPtr /*params*/) +void PrintViewManagerQt::RequestPrintPreview(printing::mojom::RequestPrintPreviewParamsPtr params) { + if (!m_printPreviewRfh && params->webnode_only) { + // The preview was requested by the print button of PDF viewer plugin. The code path ends up here, because + // Chromium automatically initiated a preview generation. We don't want that, just notify our embedder + // like we do in SetupScriptedPrintPreview() after window.print() and let them decide what to do. + content::WebContentsView *view = static_cast<content::WebContentsImpl*>(web_contents()->GetOutermostWebContents())->GetView(); + if (WebContentsAdapterClient *client = WebContentsViewQt::from(view)->client()) + client->printRequested(); + return; + } + if (m_printSettings.empty()) { PrintPreviewDone(); return; } + mojo::AssociatedRemote<printing::mojom::PrintRenderFrame> printRenderFrame; m_printPreviewRfh->GetRemoteAssociatedInterfaces()->GetInterface(&printRenderFrame); printRenderFrame->PrintPreview(m_printSettings.Clone()); diff --git a/src/core/profile_qt.cpp b/src/core/profile_qt.cpp index 410340fb8..c912c9898 100644 --- a/src/core/profile_qt.cpp +++ b/src/core/profile_qt.cpp @@ -46,7 +46,12 @@ #endif #if BUILDFLAG(ENABLE_EXTENSIONS) +#include "base/command_line.h" #include "components/guest_view/browser/guest_view_manager.h" +#include "extensions/browser/extension_pref_value_map_factory.h" +#include "extensions/browser/extension_prefs.h" +#include "extensions/browser/extension_prefs_factory.h" +#include "extensions/browser/extensions_browser_client.h" #include "extensions/browser/pref_names.h" #include "extensions/browser/process_manager.h" #include "extensions/common/constants.h" @@ -246,6 +251,7 @@ content::FileSystemAccessPermissionContext *ProfileQt::GetFileSystemAccessPermis void ProfileQt::setupPrefService() { + const bool recreation = m_prefServiceAdapter.prefService() != nullptr; profile_metrics::SetBrowserProfileType(this, IsOffTheRecord() ? profile_metrics::BrowserProfileType::kIncognito @@ -253,12 +259,28 @@ void ProfileQt::setupPrefService() // Remove previous handler before we set a new one or we will assert // TODO: Remove in Qt6 - if (m_prefServiceAdapter.prefService() != nullptr) { + if (recreation) { user_prefs::UserPrefs::Remove(this); m_prefServiceAdapter.commit(); } m_prefServiceAdapter.setup(*m_profileAdapter); user_prefs::UserPrefs::Set(this, m_prefServiceAdapter.prefService()); + +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (recreation) { + // Recreate ExtensionPrefs to update its pointer to the new PrefService + extensions::ExtensionsBrowserClient *client = extensions::ExtensionsBrowserClient::Get(); + std::vector<extensions::EarlyExtensionPrefsObserver *> prefsObservers; + client->GetEarlyExtensionPrefsObservers(this, &prefsObservers); + extensions::ExtensionPrefs *extensionPrefs = extensions::ExtensionPrefs::Create( + this, client->GetPrefServiceForContext(this), + this->GetPath().AppendASCII(extensions::kInstallDirectoryName), + ExtensionPrefValueMapFactory::GetForBrowserContext(this), + client->AreExtensionsDisabled(*base::CommandLine::ForCurrentProcess(), this), + prefsObservers); + extensions::ExtensionPrefsFactory::GetInstance()->SetInstanceForTesting(this, base::WrapUnique(extensionPrefs)); + } +#endif } PrefServiceAdapter &ProfileQt::prefServiceAdapter() diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 3d4e5bbc2..aa903577f 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -368,6 +368,9 @@ gfx::Rect RenderWidgetHostViewQt::GetViewBounds() void RenderWidgetHostViewQt::UpdateBackgroundColor() { + if (!m_delegate) + return; + DCHECK(GetBackgroundColor()); SkColor color = *GetBackgroundColor(); diff --git a/src/core/render_widget_host_view_qt_delegate_client.cpp b/src/core/render_widget_host_view_qt_delegate_client.cpp index 1b30e9953..b66c53ceb 100644 --- a/src/core/render_widget_host_view_qt_delegate_client.cpp +++ b/src/core/render_widget_host_view_qt_delegate_client.cpp @@ -346,6 +346,7 @@ QVariant RenderWidgetHostViewQtDelegateClient::inputMethodQuery(Qt::InputMethodQ } return QVariant(); } + case Qt::ImAbsolutePosition: case Qt::ImCursorPosition: return m_cursorPosition; case Qt::ImAnchorPosition: @@ -528,7 +529,7 @@ void RenderWidgetHostViewQtDelegateClient::handleTouchEvent(QTouchEvent *event) m_eventsToNowDelta = (base::TimeTicks::Now() - eventTimestamp).InMicroseconds(); eventTimestamp += base::Microseconds(m_eventsToNowDelta); - auto touchPoints = mapTouchPointIds(event->touchPoints()); + auto touchPoints = mapTouchPointIds(event->points()); // Make sure that POINTER_DOWN action is delivered before MOVE, and MOVE before POINTER_UP std::sort(touchPoints.begin(), touchPoints.end(), [] (const TouchPoint &l, const TouchPoint &r) { return l.second.state() < r.second.state(); diff --git a/src/core/render_widget_host_view_qt_delegate_item.cpp b/src/core/render_widget_host_view_qt_delegate_item.cpp index e6145f7a6..9723fcf2c 100644 --- a/src/core/render_widget_host_view_qt_delegate_item.cpp +++ b/src/core/render_widget_host_view_qt_delegate_item.cpp @@ -22,8 +22,10 @@ RenderWidgetHostViewQtDelegateItem::RenderWidgetHostViewQtDelegateItem(RenderWid { setFlag(ItemHasContents); setAcceptedMouseButtons(Qt::AllButtons); + setKeepMouseGrab(true); setAcceptHoverEvents(true); setAcceptTouchEvents(true); + setKeepTouchGrab(true); if (!isPopup) { setFocus(true); setActiveFocusOnTab(true); diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index d0da744d7..973da88a7 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -4,6 +4,7 @@ #include "web_engine_context.h" #include <math.h> +#include <QtGui/private/qrhi_p.h> #include "base/base_switches.h" #include "base/bind.h" @@ -177,6 +178,31 @@ bool usingSoftwareDynamicGL() #endif } +#if defined(Q_OS_WIN) +static QString getAdapterLuid() { + static const bool preferSoftwareDevice = qEnvironmentVariableIntValue("QSG_RHI_PREFER_SOFTWARE_RENDERER"); + QRhiD3D11InitParams rhiParams; + QRhi::Flags flags; + if (preferSoftwareDevice) { + flags |= QRhi::PreferSoftwareRenderer; + } + QScopedPointer<QRhi> rhi(QRhi::create(QRhi::D3D11,&rhiParams,flags,nullptr)); + // mimic what QSGRhiSupport and QBackingStoreRhi does + if (!rhi && !preferSoftwareDevice) { + flags |= QRhi::PreferSoftwareRenderer; + rhi.reset(QRhi::create(QRhi::D3D11, &rhiParams, flags)); + } + if (rhi) { + const QRhiD3D11NativeHandles *handles = + static_cast<const QRhiD3D11NativeHandles *>(rhi->nativeHandles()); + Q_ASSERT(handles); + return QString("%1,%2").arg(handles->adapterLuidHigh).arg(handles->adapterLuidLow); + } else { + return QString(); + } +} +#endif + static bool openGLPlatformSupport() { return QGuiApplicationPrivate::platformIntegration()->hasCapability( @@ -727,6 +753,14 @@ WebEngineContext::WebEngineContext() } #endif +#if defined(Q_OS_WIN) + if (QQuickWindow::graphicsApi() == QSGRendererInterface::Direct3D11) { + const QString luid = getAdapterLuid(); + if (!luid.isEmpty()) + parsedCommandLine->AppendSwitchASCII(switches::kUseAdapterLuid, luid.toStdString()); + } +#endif + initializeFeatureList(parsedCommandLine, enableFeatures, disableFeatures); GLContextHelper::initialize(); @@ -937,7 +971,7 @@ const char *qWebEngineChromiumVersion() noexcept const char *qWebEngineChromiumSecurityPatchVersion() noexcept { - return "114.0.5735.133"; // FIXME: Remember to update + return "117.0.5938.63"; // FIXME: Remember to update } QT_END_NAMESPACE diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp index 508a4b557..b2fb74016 100644 --- a/src/core/web_event_factory.cpp +++ b/src/core/web_event_factory.cpp @@ -558,6 +558,8 @@ static int windowsKeyCodeForQtKey(int qtKey, bool isKeypad) case Qt::Key_QuoteDbl: return VK_OEM_7; // case '\'': case '"': return 0xDE; // VK_OEM_8 (DF) Used for miscellaneous characters; it can vary by keyboard. + case Qt::Key_AltGr: + return 0xE1; // (E1) VK_OEM_AX = ui::VKEY_ALTGR see ui/events/keycodes/keyboard_codes_win.h // VK_OEM_102 (E2) Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard case Qt::Key_AudioRewind: @@ -1677,10 +1679,12 @@ content::NativeWebKeyboardEvent WebEventFactory::toWebKeyboardEvent(QKeyEvent *e ui::DomCodeToUsLayoutKeyboardCode(static_cast<ui::DomCode>(webKitEvent.dom_code)); const ushort* text = qtText.utf16(); - size_t textSize = std::min(sizeof(webKitEvent.text), size_t(qtText.length() * 2)); - memcpy(&webKitEvent.text, text, textSize); - memcpy(&webKitEvent.unmodified_text, text, textSize); - + size_t size = std::char_traits<char16_t>::length((char16_t *)text); + if (size <= blink::WebKeyboardEvent::kTextLengthCap - 1) { // should be null terminated + size_t textSize = std::min(sizeof(webKitEvent.text), size * sizeof(char16_t)); + memcpy(&webKitEvent.text, text, textSize); + memcpy(&webKitEvent.unmodified_text, text, textSize); + } if (webKitEvent.windows_key_code == VK_RETURN) { // This is the same behavior as GTK: // We need to treat the enter key as a key press of character \r. This diff --git a/src/host/CMakeLists.txt b/src/host/CMakeLists.txt index 59e003025..d579a61b8 100644 --- a/src/host/CMakeLists.txt +++ b/src/host/CMakeLists.txt @@ -52,3 +52,17 @@ if(QT_FEATURE_qtpdf_build) ) endif() +# TODO: this could be run as part of main configure with execute_process + +if(CMAKE_CXX_COMPILER_ID STREQUAL GNU AND TEST_architecture_arch STREQUAL "x86_64" +AND GN_TARGET_CPU STREQUAL "arm") + try_compile( + has32HostCompiler + "${CMAKE_CURRENT_BINARY_DIR}/config.tests/hostcompiler" + "${CMAKE_CURRENT_SOURCE_DIR}/config.tests/hostcompiler" + hostcompiler + ) + if(NOT has32HostCompiler) + MESSAGE(FATAL_ERROR "Compiler does not support 32bit compilation") + endif() +endif() diff --git a/src/host/config.tests/hostcompiler/CMakeLists.txt b/src/host/config.tests/hostcompiler/CMakeLists.txt new file mode 100644 index 000000000..f36886d0a --- /dev/null +++ b/src/host/config.tests/hostcompiler/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(arch LANGUAGES CXX) + +add_executable(host_compiler_test) +set_property(TARGET host_compiler_test PROPERTY MACOSX_BUNDLE FALSE) +target_sources(host_compiler_test PRIVATE main.cpp) +target_compile_options(host_compiler_test PRIVATE -m32) +target_link_options(host_compiler_test PRIVATE -m32) diff --git a/config.tests/hostcompiler/main.cpp b/src/host/config.tests/hostcompiler/main.cpp index 1676f7a26..1676f7a26 100644 --- a/config.tests/hostcompiler/main.cpp +++ b/src/host/config.tests/hostcompiler/main.cpp diff --git a/src/pdf/doc/about_credits_entry.tmpl b/src/pdf/doc/about_credits_entry.tmpl index 294198709..c6dc90242 100644 --- a/src/pdf/doc/about_credits_entry.tmpl +++ b/src/pdf/doc/about_credits_entry.tmpl @@ -1,6 +1,5 @@ /*! -\page qtpdf-3rdparty-{{name-sanitized}}.html -\attribution +\page qtpdf-3rdparty-{{name-sanitized}}.html attribution \ingroup qtpdf-licensing \brief {{license-type}} \title {{name}} diff --git a/src/pdf/doc/src/qtpdf-index.qdoc b/src/pdf/doc/src/qtpdf-index.qdoc index fb44eb5fa..b72619fbf 100644 --- a/src/pdf/doc/src/qtpdf-index.qdoc +++ b/src/pdf/doc/src/qtpdf-index.qdoc @@ -17,7 +17,7 @@ and holds the search results. The QPdfBookmarkModel class holds the table of contents, if present. The QPdfLinkModel holds information about hyperlinks on a page. The \l QPdfView widget is a complete - PDF viewer, and the \l {PDF Viewer Example} shows how to use it. + PDF viewer, and the \l {PDF Viewer Widget Example} shows how to use it. For Qt Quick applications, three kinds of full-featured viewer components are provided. \l PdfMultiPageView should be your @@ -65,6 +65,11 @@ \li \l{Qt Quick PDF QML Types} \endlist + \section1 Articles and Guides + \list + \li {Qt PDF Platform Notes} {Platform Notes} + \endlist + \section1 Licenses and Attributions Qt PDF is available under commercial licenses from \l{The Qt Company}. diff --git a/src/pdf/doc/src/qtpdf-platformnotes.qdoc b/src/pdf/doc/src/qtpdf-platformnotes.qdoc new file mode 100644 index 000000000..f50be120d --- /dev/null +++ b/src/pdf/doc/src/qtpdf-platformnotes.qdoc @@ -0,0 +1,11 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \page qtpdf-platformnotes.html + \title Qt PDF Platform Notes + + Building Qt PDF for Android is currently + \l{https://bugreports.qt.io/browse/QTBUG-83459} {not supported} on Windows host platforms. +*/ + diff --git a/src/pdf/qpdfbookmarkmodel.cpp b/src/pdf/qpdfbookmarkmodel.cpp index c9035f21a..78d89cc9b 100644 --- a/src/pdf/qpdfbookmarkmodel.cpp +++ b/src/pdf/qpdfbookmarkmodel.cpp @@ -176,17 +176,7 @@ struct QPdfBookmarkModelPrivate const FPDF_DEST dest = FPDFBookmark_GetDest(document, bookmark); const int pageNumber = FPDFDest_GetDestPageIndex(document, dest); - double pageHeight = 11.69 * 72; // A4 height - { - // get actual page height - const QPdfMutexLocker lock; - FPDF_PAGE pdfPage = FPDF_LoadPage(document, pageNumber); - if (pdfPage) - pageHeight = FPDF_GetPageHeight(pdfPage); - else - qCWarning(qLcBM) << "failed to load page" << pageNumber; - } - + const qreal pageHeight = m_document->pagePointSize(pageNumber).height(); FPDF_BOOL hasX, hasY, hasZoom; FS_FLOAT x, y, zoom; bool ok = FPDFDest_GetLocationInPage(dest, &hasX, &hasY, &hasZoom, &x, &y, &zoom); diff --git a/src/pdf/qpdfpagenavigator.cpp b/src/pdf/qpdfpagenavigator.cpp index 253c1dff8..e077e2184 100644 --- a/src/pdf/qpdfpagenavigator.cpp +++ b/src/pdf/qpdfpagenavigator.cpp @@ -207,9 +207,9 @@ void QPdfPageNavigator::jump(QPdfLink destination) emit currentLocationChanged(currentLocation()); if (d->changing) return; - if (!backAvailableWas) + if (backAvailableWas != backAvailable()) emit backAvailableChanged(backAvailable()); - if (forwardAvailableWas) + if (forwardAvailableWas != forwardAvailable()) emit forwardAvailableChanged(forwardAvailable()); emit jumped(currentLink()); qCDebug(qLcNav) << "push: index" << d->currentHistoryIndex << destination << "-> history" << @@ -263,9 +263,9 @@ void QPdfPageNavigator::jump(int page, const QPointF &location, qreal zoom) emit currentLocationChanged(currentLocation()); if (d->changing) return; - if (!backAvailableWas) + if (backAvailableWas != backAvailable()) emit backAvailableChanged(backAvailable()); - if (forwardAvailableWas) + if (forwardAvailableWas != forwardAvailable()) emit forwardAvailableChanged(forwardAvailable()); emit jumped(currentLink()); qCDebug(qLcNav) << "push: index" << d->currentHistoryIndex << "page" << page diff --git a/src/pdf/qpdfsearchmodel.cpp b/src/pdf/qpdfsearchmodel.cpp index 3109430f0..90be76b8e 100644 --- a/src/pdf/qpdfsearchmodel.cpp +++ b/src/pdf/qpdfsearchmodel.cpp @@ -196,21 +196,13 @@ void QPdfSearchModel::setDocument(QPdfDocument *document) disconnect(d->documentConnection); d->documentConnection = connect(document, &QPdfDocument::pageCountChanged, this, - &QPdfSearchModel::onDocumentPageCountChanged); + [this]() { d_func()->clearResults(); }); d->document = document; d->clearResults(); emit documentChanged(); } -void QPdfSearchModel::onDocumentPageCountChanged(int count) -{ - Q_UNUSED(count); - - Q_D(QPdfSearchModel); - d->clearResults(); -} - void QPdfSearchModel::timerEvent(QTimerEvent *event) { Q_D(QPdfSearchModel); diff --git a/src/pdf/qpdfsearchmodel.h b/src/pdf/qpdfsearchmodel.h index b1094b67b..c1e4e64ec 100644 --- a/src/pdf/qpdfsearchmodel.h +++ b/src/pdf/qpdfsearchmodel.h @@ -55,7 +55,6 @@ Q_SIGNALS: protected: void updatePage(int page); void timerEvent(QTimerEvent *event) override; - void onDocumentPageCountChanged(int count); private: QHash<int, QByteArray> m_roleNames; diff --git a/src/pdfquick/PdfMultiPageView.qml b/src/pdfquick/PdfMultiPageView.qml index 0f62a229d..10683f55d 100644 --- a/src/pdfquick/PdfMultiPageView.qml +++ b/src/pdfquick/PdfMultiPageView.qml @@ -298,14 +298,7 @@ Item { property point jumpLocationMargin: Qt.point(10, 10) // px away from viewport edges anchors.fill: parent anchors.leftMargin: 2 - model: modelInUse && root.document ? root.document.pageCount : 0 - // workaround to make TableView do scheduleRebuildTable(RebuildOption::All) in cases when forceLayout() doesn't - property bool modelInUse: true - function rebuild() { - modelInUse = false - modelInUse = true - } - // end workaround + model: root.document ? root.document.pageCount : 0 rowSpacing: 6 property real rotationNorm: Math.round((360 + (root.pageRotation % 360)) % 360) property bool rot90: rotationNorm == 90 || rotationNorm == 270 @@ -528,8 +521,8 @@ Item { // and don't force layout either, because positionViewAtCell() will do that if (pageNavigator.jumping) return - // make TableView rebuild from scratch, because otherwise it doesn't know the delegates are changing size - tableView.rebuild() + // page size changed: TableView needs to redo layout to avoid overlapping delegates or gaps between them + tableView.forceLayout() const cell = tableView.cellAtPos(root.width / 2, root.height / 2) const currentItem = tableView.itemAtCell(cell) if (currentItem) { diff --git a/src/pdfquick/doc/src/qtquickpdf-module.qdoc b/src/pdfquick/doc/src/qtquickpdf-module.qdoc index 1d31f6148..a4ca0d9e8 100644 --- a/src/pdfquick/doc/src/qtquickpdf-module.qdoc +++ b/src/pdfquick/doc/src/qtquickpdf-module.qdoc @@ -12,7 +12,7 @@ To use the types in this module, import the module with the following line: - \code + \qml import QtQuick.Pdf - \endcode + \endqml */ diff --git a/src/pdfquick/qquickpdfdocument.cpp b/src/pdfquick/qquickpdfdocument.cpp index 492c320d6..a9f0d196e 100644 --- a/src/pdfquick/qquickpdfdocument.cpp +++ b/src/pdfquick/qquickpdfdocument.cpp @@ -36,7 +36,10 @@ QQuickPdfDocument::QQuickPdfDocument(QObject *parent) /*! \internal */ -QQuickPdfDocument::~QQuickPdfDocument() = default; +QQuickPdfDocument::~QQuickPdfDocument() +{ + delete m_carrierFile; +}; void QQuickPdfDocument::classBegin() { diff --git a/src/pdfwidgets/qpdfview.cpp b/src/pdfwidgets/qpdfview.cpp index 831b51515..6e65639f0 100644 --- a/src/pdfwidgets/qpdfview.cpp +++ b/src/pdfwidgets/qpdfview.cpp @@ -14,7 +14,6 @@ #include <QPdfPageNavigator> #include <QScreen> #include <QScrollBar> -#include <QScroller> QT_BEGIN_NAMESPACE @@ -281,8 +280,6 @@ QPdfView::QPdfView(QWidget *parent) verticalScrollBar()->setSingleStep(20); horizontalScrollBar()->setSingleStep(20); - QScroller::grabGesture(this); - d->calculateViewport(); } diff --git a/src/process/CMakeLists.txt b/src/process/CMakeLists.txt index 63783af69..80cc238f9 100644 --- a/src/process/CMakeLists.txt +++ b/src/process/CMakeLists.txt @@ -88,7 +88,8 @@ if(isFramework) COMPONENT Runtime ) qt_enable_separate_debug_info(${qtWebEngineProcessName} - "${INSTALL_LIBDIR}/QtWebEngineCore.framework/Versions/A/Helpers" QT_EXECUTABLE + "${INSTALL_LIBDIR}" QT_EXECUTABLE + DSYM_OUTPUT_DIR "${CMAKE_BINARY_DIR}/${INSTALL_LIBDIR}" ) else() qt_apply_rpaths(TARGET ${qtWebEngineProcessName} INSTALL_PATH "${INSTALL_LIBEXECDIR}" RELATIVE_RPATH) diff --git a/src/webenginequick/api/qquickwebengineforeigntypes_p.h b/src/webenginequick/api/qquickwebengineforeigntypes_p.h index 1591e596f..b5f3b3c22 100644 --- a/src/webenginequick/api/qquickwebengineforeigntypes_p.h +++ b/src/webenginequick/api/qquickwebengineforeigntypes_p.h @@ -53,10 +53,17 @@ struct ForeignWebEngineLoadingInfo QML_UNCREATABLE("") }; +// To prevent the same type from being exported twice into qmltypes +// (for value type and for the enums) +struct QWebEngineCertificateErrorDerived : public QWebEngineCertificateError +{ + Q_GADGET +}; + namespace ForeignWebEngineCertificateErrorNamespace { Q_NAMESPACE - QML_FOREIGN_NAMESPACE(QWebEngineCertificateError) + QML_FOREIGN_NAMESPACE(QWebEngineCertificateErrorDerived) QML_NAMED_ELEMENT(WebEngineCertificateError) QML_ADDED_IN_VERSION(1, 1) QML_EXTRA_VERSION(2, 0) @@ -141,6 +148,7 @@ struct ForeignWebEngineContextMenuRequest QML_UNCREATABLE("") }; +#if QT_DEPRECATED_SINCE(6, 5) struct ForeignWebEngineQuotaRequest { Q_GADGET @@ -150,6 +158,7 @@ struct ForeignWebEngineQuotaRequest QML_EXTRA_VERSION(2, 0) QML_UNCREATABLE("") }; +#endif struct ForeignWebEngineRegisterProtocolHandlerRequest { diff --git a/src/webenginequick/api/qquickwebengineview.cpp b/src/webenginequick/api/qquickwebengineview.cpp index 5e248327d..cd73749c9 100644 --- a/src/webenginequick/api/qquickwebengineview.cpp +++ b/src/webenginequick/api/qquickwebengineview.cpp @@ -77,6 +77,8 @@ QT_BEGIN_NAMESPACE using namespace QtWebEngineCore; +using LoadStatus = QWebEngineLoadingInfo::LoadStatus; +using ErrorDomain = QWebEngineLoadingInfo::ErrorDomain; #if QT_DEPRECATED_SINCE(6, 2) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::AcceptRequest) == static_cast<int>(QWebEngineNavigationRequest::AcceptRequest)); @@ -92,9 +94,6 @@ Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::NewViewInWindow) Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::NewViewInTab) == static_cast<int>(QWebEngineNewWindowRequest::InNewTab)); Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::NewViewInDialog) == static_cast<int>(QWebEngineNewWindowRequest::InNewDialog)); Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::NewViewInBackgroundTab) == static_cast<int>(QWebEngineNewWindowRequest::InNewBackgroundTab)); - -using LoadStatus = QWebEngineLoadingInfo::LoadStatus; -using ErrorDomain = QWebEngineLoadingInfo::ErrorDomain; Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::NoErrorDomain) == static_cast<int>(ErrorDomain::NoErrorDomain)); Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::InternalErrorDomain) == static_cast<int>(ErrorDomain::InternalErrorDomain)); Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::ConnectionErrorDomain) == static_cast<int>(ErrorDomain::ConnectionErrorDomain)); diff --git a/src/webenginequick/doc/snippets/qtwebengine_build_snippet.qdoc b/src/webenginequick/doc/snippets/qtwebengine_build_snippet.qdoc index 76dea97cf..f8fbbd669 100644 --- a/src/webenginequick/doc/snippets/qtwebengine_build_snippet.qdoc +++ b/src/webenginequick/doc/snippets/qtwebengine_build_snippet.qdoc @@ -7,5 +7,5 @@ QT += webenginequick //! [2] find_package(Qt6 REQUIRED COMPONENTS WebEngineQuick) -target_link_libraries(target PRIVATE Qt::WebEngineQuick) +target_link_libraries(target PRIVATE Qt6::WebEngineQuick) //! [2] diff --git a/src/webenginequick/doc/src/webengineview_lgpl.qdoc b/src/webenginequick/doc/src/webengineview_lgpl.qdoc index 6390c0c02..358f8b1dd 100644 --- a/src/webenginequick/doc/src/webengineview_lgpl.qdoc +++ b/src/webenginequick/doc/src/webengineview_lgpl.qdoc @@ -1315,10 +1315,11 @@ */ /*! - \qmlsignal WebEngineView::printRequest + \qmlsignal WebEngineView::printRequested \since QtWebEngine 1.8 - This signal is emitted when the JavaScript \c{window.print()} method is called. + This signal is emitted when the JavaScript \c{window.print()} method is called or the user pressed the print + button of PDF viewer plugin. Typically, the signal handler can simply call printToPdf(). \sa printToPdf diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp index 35fb98138..8d88726fa 100644 --- a/src/webenginewidgets/api/qwebengineview.cpp +++ b/src/webenginewidgets/api/qwebengineview.cpp @@ -1379,7 +1379,8 @@ void QWebEngineView::printToPdf(const std::function<void(const QByteArray&)> &re \fn void QWebEngineView::printRequested() \since 6.2 - This signal is emitted when the JavaScript \c{window.print()} method is called. + This signal is emitted when the JavaScript \c{window.print()} method is called or the user pressed the print + button of PDF viewer plugin. Typically, the signal handler can simply call print(). \sa print() diff --git a/src/webenginewidgets/doc/snippets/qtwebenginewidgets_build_snippet.qdoc b/src/webenginewidgets/doc/snippets/qtwebenginewidgets_build_snippet.qdoc index 4ab54a2ba..f11f550ff 100644 --- a/src/webenginewidgets/doc/snippets/qtwebenginewidgets_build_snippet.qdoc +++ b/src/webenginewidgets/doc/snippets/qtwebenginewidgets_build_snippet.qdoc @@ -7,5 +7,5 @@ QT += webenginewidgets //! [2] find_package(Qt6 REQUIRED COMPONENTS WebEngineWidgets) -target_link_libraries(target PRIVATE Qt::WebEngineWidgets) +target_link_libraries(target PRIVATE Qt6::WebEngineWidgets) //! [2] diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc index 84f71cf10..9b8ee29eb 100644 --- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc @@ -61,7 +61,7 @@ new windows, such as pop-up windows, you can subclass QWebEngineView and reimplement the createWindow() function. - \sa {WebEngine Widgets Simple Browser Example}, {WebEngine Content Manipulation Example}, {WebEngine Recipe Browser Example} + \sa {WebEngine Widgets Simple Browser Example}, {WebEngine Content Manipulation Example} */ diff --git a/src/webenginewidgets/plugins/qwebengineview/qwebengineview_plugin.cpp b/src/webenginewidgets/plugins/qwebengineview/qwebengineview_plugin.cpp index 2ff1de169..6ba64a178 100644 --- a/src/webenginewidgets/plugins/qwebengineview/qwebengineview_plugin.cpp +++ b/src/webenginewidgets/plugins/qwebengineview/qwebengineview_plugin.cpp @@ -79,14 +79,6 @@ void QWebEngineViewPlugin::initialize(QDesignerFormEditorInterface * /*core*/) QString QWebEngineViewPlugin::domXml() const { - const auto graphicsApi = QQuickWindow::graphicsApi(); - if (graphicsApi != QSGRendererInterface::OpenGLRhi - && graphicsApi != QSGRendererInterface::Software) { - qWarning("Qt Designer: The QWebEngineView custom widget plugin is disabled because it requires OpenGL/Software RHI (current: %d).", - int(graphicsApi)); - return {}; - } - return QStringLiteral("\ <ui language=\"c++\">\ <widget class=\"QWebEngineView\" name=\"webEngineView\">\ diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt index 6fff2b35c..ad69710b1 100644 --- a/tests/auto/CMakeLists.txt +++ b/tests/auto/CMakeLists.txt @@ -13,5 +13,7 @@ if(TARGET Qt::WebEngineWidgets) endif() if(TARGET Qt::Pdf) add_subdirectory(pdf) +endif() +if(TARGET Qt::PdfQuick) add_subdirectory(pdfquick) endif() diff --git a/tests/auto/pdf/CMakeLists.txt b/tests/auto/pdf/CMakeLists.txt index 8bda0c3c3..2f3f73961 100644 --- a/tests/auto/pdf/CMakeLists.txt +++ b/tests/auto/pdf/CMakeLists.txt @@ -2,7 +2,9 @@ # SPDX-License-Identifier: BSD-3-Clause add_subdirectory(qpdfbookmarkmodel) -#add_subdirectory(qpdfpagenavigator) +if (TARGET Qt::PdfWidgets) + add_subdirectory(qpdfpagenavigator) +endif() add_subdirectory(qpdfpagerenderer) if(TARGET Qt::PrintSupport) add_subdirectory(qpdfdocument) diff --git a/tests/auto/pdf/qpdfpagenavigator/CMakeLists.txt b/tests/auto/pdf/qpdfpagenavigator/CMakeLists.txt new file mode 100644 index 000000000..3e8b8f416 --- /dev/null +++ b/tests/auto/pdf/qpdfpagenavigator/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_test(tst_qpdfpagenavigator.cpp + SOURCES + tst_qpdfpagenavigator.cpp + LIBRARIES + Qt::Gui + Qt::Network + Qt::Pdf + Qt::PdfWidgets + TESTDATA + pdf-sample.bookmarks_pages.pdf +) diff --git a/tests/auto/pdf/qpdfpagenavigator/pdf-sample.bookmarks_pages.pdf b/tests/auto/pdf/qpdfpagenavigator/pdf-sample.bookmarks_pages.pdf Binary files differnew file mode 100644 index 000000000..c4e1aa36e --- /dev/null +++ b/tests/auto/pdf/qpdfpagenavigator/pdf-sample.bookmarks_pages.pdf diff --git a/tests/auto/pdf/qpdfpagenavigator/tst_qpdfpagenavigator.cpp b/tests/auto/pdf/qpdfpagenavigator/tst_qpdfpagenavigator.cpp new file mode 100644 index 000000000..327a9f36a --- /dev/null +++ b/tests/auto/pdf/qpdfpagenavigator/tst_qpdfpagenavigator.cpp @@ -0,0 +1,70 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + + +#include <QtTest/QtTest> + +#include <QPdfDocument> +#include <QPdfView> +#include <QPdfPageNavigator> + +class tst_QPdfPageNavigator: public QObject +{ + Q_OBJECT + +private slots: + void offScreenSignals(); +}; + +void tst_QPdfPageNavigator::offScreenSignals() +{ + QPdfDocument document; + QPdfView pdfView; + QPdfPageNavigator *navigator = pdfView.pageNavigator(); + + QSignalSpy currentPageChanged(navigator, &QPdfPageNavigator::currentPageChanged); + QSignalSpy currentLocationChanged(navigator, &QPdfPageNavigator::currentLocationChanged); + QSignalSpy backAvailableChanged(navigator, &QPdfPageNavigator::backAvailableChanged); + QSignalSpy forwardAvailableChanged(navigator, &QPdfPageNavigator::forwardAvailableChanged); + QSignalSpy jumped(navigator, &QPdfPageNavigator::jumped); + + QCOMPARE(document.load(QFINDTESTDATA("pdf-sample.bookmarks_pages.pdf")), QPdfDocument::Error::None); + QVERIFY2(document.pageCount() == 3, "Test document has changed! 3 pages expected."); + pdfView.setDocument(&document); + + // Start with a clean history + QCOMPARE(forwardAvailableChanged.count(), 0); + QCOMPARE(backAvailableChanged.count(), 0); + + navigator->jump(3, QPoint()); + QCOMPARE(forwardAvailableChanged.count(), 0); + QCOMPARE(backAvailableChanged.count(), 1); + QCOMPARE(currentPageChanged.count(), 1); + QCOMPARE(currentLocationChanged.count(), 0); + QCOMPARE(jumped.count(), 1); + + navigator->jump(1, QPoint()); + QCOMPARE(forwardAvailableChanged.count(), 0); + QCOMPARE(backAvailableChanged.count(), 1); + QCOMPARE(currentPageChanged.count(), 2); + QCOMPARE(currentLocationChanged.count(), 0); + QCOMPARE(jumped.count(), 2); + + navigator->back(); + QCOMPARE(forwardAvailableChanged.count(), 1); + QCOMPARE(backAvailableChanged.count(), 1); + QCOMPARE(currentPageChanged.count(), 3); + QCOMPARE(currentLocationChanged.count(), 0); + QCOMPARE(jumped.count(), 3); + + navigator->forward(); + QCOMPARE(forwardAvailableChanged.count(), 2); + QCOMPARE(backAvailableChanged.count(), 1); + QCOMPARE(currentPageChanged.count(), 4); + QCOMPARE(currentLocationChanged.count(), 0); + QCOMPARE(jumped.count(), 4); +} + +QTEST_MAIN(tst_QPdfPageNavigator) + +#include "tst_qpdfpagenavigator.moc" diff --git a/tests/auto/quick/qmltests/CMakeLists.txt b/tests/auto/quick/qmltests/CMakeLists.txt index 542e44706..c102b2433 100644 --- a/tests/auto/quick/qmltests/CMakeLists.txt +++ b/tests/auto/quick/qmltests/CMakeLists.txt @@ -25,6 +25,7 @@ set(testList tst_datalist.qml tst_desktopBehaviorLoadHtml.qml tst_download.qml + tst_dragHandlerUnderView.qml tst_favicon.qml tst_faviconDatabase.qml tst_filePicker.qml diff --git a/tests/auto/quick/qmltests/data/tst_dragHandlerUnderView.qml b/tests/auto/quick/qmltests/data/tst_dragHandlerUnderView.qml new file mode 100644 index 000000000..c22bd44c2 --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_dragHandlerUnderView.qml @@ -0,0 +1,67 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtTest +import QtWebEngine + +Item { + id: parentItem + width: 400 + height: 300 + + Rectangle { + id: draggableDownUnder + color: "wheat" + width: 350 + height: 250 + + DragHandler { id: dragHandler } + } + + TestWebEngineView { + id: webEngineView + width: 300 + height: 250 + + property var testUrl: Qt.resolvedUrl("test4.html") + + SignalSpy { + id: scrollPositionSpy + target: webEngineView + signalName: "onScrollPositionChanged" + } + + SignalSpy { + id: dragActiveSpy + target: dragHandler + signalName: "activeChanged" + } + + TestCase { + id: testCase + name: "KeepMouseGrabDuringScrolling" + when: windowShown + + function test_scroll() { + webEngineView.url = Qt.resolvedUrl("test4.html"); + verify(webEngineView.waitForLoadSucceeded()); + + mousePress(webEngineView, 295, 20); + mouseMove(webEngineView, 295, 200); + mouseRelease(webEngineView, 295, 200); + + // WebEngineView scrolled if the scrollbar was visible. + // But on macOS, the scrollbar is hidden, so text gets selected. + tryVerify(function() { + return (scrollPositionSpy.count === 1 && webEngineView.scrollPosition.y > 100) + || webEngineView.getTextSelection().length > 0; + }); + + // DragHandler didn't take over and drag + compare(dragActiveSpy.count, 0); + compare(draggableDownUnder.y, 0); + } + } + } +} diff --git a/tests/auto/quick/qmltests/data/tst_filePicker.qml b/tests/auto/quick/qmltests/data/tst_filePicker.qml index a557369ed..a7b59b2e9 100644 --- a/tests/auto/quick/qmltests/data/tst_filePicker.qml +++ b/tests/auto/quick/qmltests/data/tst_filePicker.qml @@ -11,7 +11,6 @@ TestWebEngineView { id: webEngineView width: 400 height: 300 - property var titleChanges: [] function driveLetter() { if (Qt.platform.os !== "windows") @@ -30,8 +29,6 @@ TestWebEngineView { signalName: "renderProcessTerminated" } - onTitleChanged: { titleChanges.push(webEngineView.title) } - TestCase { id: testCase name: "WebEngineViewSingleFileUpload" @@ -44,7 +41,6 @@ TestWebEngineView { FilePickerParams.nameFilters = [] titleSpy.clear() terminationSpy.clear() - titleChanges = [] } function cleanup() { @@ -87,10 +83,10 @@ TestWebEngineView { keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog. tryCompare(FilePickerParams, "filePickerOpened", true); + tryCompare(webEngineView, "title", row.expected); webEngineView.url = Qt.resolvedUrl("about:blank"); verify(webEngineView.waitForLoadSucceeded()); tryCompare(webEngineView, "title", "about:blank"); - compare(titleChanges[titleChanges.length-2], row.expected); // Custom dialog @@ -98,7 +94,7 @@ TestWebEngineView { function acceptedFileHandler(request) { request.accepted = true; - request.dialogAccept(row.input); + request.dialogAccept([row.input]); finished = true; } @@ -108,10 +104,10 @@ TestWebEngineView { keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog. tryVerify(function() { return finished; }); + tryCompare(webEngineView, "title", row.expected); webEngineView.url = Qt.resolvedUrl("about:blank"); verify(webEngineView.waitForLoadSucceeded()); tryCompare(webEngineView, "title", "about:blank"); - compare(titleChanges[titleChanges.length-2], row.expected); webEngineView.fileDialogRequested.disconnect(acceptedFileHandler); } @@ -242,10 +238,10 @@ TestWebEngineView { keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog. tryCompare(FilePickerParams, "filePickerOpened", true); + tryCompare(webEngineView, "title", row.expected); webEngineView.url = Qt.resolvedUrl("about:blank"); verify(webEngineView.waitForLoadSucceeded()); tryCompare(webEngineView, "title", "about:blank"); - compare(titleChanges[titleChanges.length-2], row.expected); // Custom dialog @@ -253,7 +249,7 @@ TestWebEngineView { function acceptedFileHandler(request) { request.accepted = true; - request.dialogAccept(row.input); + request.dialogAccept([row.input]); finished = true; } @@ -263,10 +259,10 @@ TestWebEngineView { keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog. tryVerify(function() { return finished; }); + tryCompare(webEngineView, "title", row.expected); webEngineView.url = Qt.resolvedUrl("about:blank"); verify(webEngineView.waitForLoadSucceeded()); tryCompare(webEngineView, "title", "about:blank"); - compare(titleChanges[titleChanges.length-2], row.expected); webEngineView.fileDialogRequested.disconnect(acceptedFileHandler); } diff --git a/tests/auto/widgets/proxy/tst_proxy.cpp b/tests/auto/widgets/proxy/tst_proxy.cpp index f378ae22f..3dc72618c 100644 --- a/tests/auto/widgets/proxy/tst_proxy.cpp +++ b/tests/auto/widgets/proxy/tst_proxy.cpp @@ -8,7 +8,7 @@ #include <QWebEnginePage> #include <QWebEngineView> #include <QWebEngineUrlRequestInterceptor> - +#include <QWebEngineLoadingInfo> struct Interceptor : public QWebEngineUrlRequestInterceptor { @@ -28,6 +28,7 @@ public: private slots: void proxyAuthentication(); void forwardCookie(); + void invalidHostName(); }; @@ -72,6 +73,19 @@ void tst_Proxy::forwardCookie() QTRY_VERIFY2(cookieSpy.size() > 0, "Could not get cookie"); } +// Crash test ( https://bugreports.qt.io/browse/QTBUG-113992 ) +void tst_Proxy::invalidHostName() +{ + QNetworkProxy proxy; + proxy.setType(QNetworkProxy::HttpProxy); + proxy.setHostName("999.0.0.0"); + QNetworkProxy::setApplicationProxy(proxy); + QWebEnginePage page; + QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool))); + page.load(QUrl("http://www.qt.io")); + QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000); +} + #include "tst_proxy.moc" QTEST_MAIN(tst_Proxy) diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index ba88fd99e..132cefb04 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -3076,7 +3076,7 @@ void tst_QWebEnginePage::loadInSignalHandlers() URLSetter setter(m_page, signal, type, urlForSetter); QSignalSpy spy(&setter, &URLSetter::finished); m_page->load(url); - QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 20000); + QTRY_VERIFY_WITH_TIMEOUT(spy.size() >= 1, 20000); QCOMPARE(m_page->url(), urlForSetter); } diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index 15e226139..6dd75a7eb 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -183,6 +183,7 @@ private Q_SLOTS: void navigateOnDrop_data(); void navigateOnDrop(); void datalist(); + void longKeyEventText(); }; // This will be called before the first test function is executed. @@ -1353,18 +1354,20 @@ void tst_QWebEngineView::inputMethodsTextFormat_data() void tst_QWebEngineView::inputMethodsTextFormat() { - QWebEngineView view; - view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true); - QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool))); - - view.setHtml("<html><body>" - " <input type='text' id='input1' style='font-family: serif' value='' maxlength='20'/>" - "</body></html>"); + QWebEnginePage page; + QWebEngineView view(&page); + page.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true); + QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool))); + + page.setHtml( + "<html><body>" + " <input type='text' id='input1' style='font-family: serif' value='' maxlength='20'/>" + "</body></html>"); QTRY_COMPARE(loadFinishedSpy.size(), 1); - evaluateJavaScriptSync(view.page(), "document.getElementById('input1').focus()"); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); + evaluateJavaScriptSync(&page, "document.getElementById('input1').focus()"); QFETCH(QString, string); QFETCH(int, start); @@ -1388,8 +1391,10 @@ void tst_QWebEngineView::inputMethodsTextFormat() attrs.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, start, length, format)); QInputMethodEvent im(string, attrs); - QVERIFY(QApplication::sendEvent(view.focusProxy(), &im)); - QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), string); + QApplication::sendEvent(view.focusProxy(), &im); + QTRY_COMPARE_WITH_TIMEOUT( + evaluateJavaScriptSync(&page, "document.getElementById('input1').value").toString(), + string, 20000); } void tst_QWebEngineView::keyboardEvents() @@ -2309,22 +2314,19 @@ void tst_QWebEngineView::textSelectionOutOfInputField() // Select text by ctrl+a QTest::keyClick(view.windowHandle(), Qt::Key_A, Qt::ControlModifier); - QVERIFY(selectionChangedSpy.wait()); - QCOMPARE(selectionChangedSpy.size(), 1); + QTRY_COMPARE(selectionChangedSpy.size(), 1); QVERIFY(view.hasSelection()); QCOMPARE(view.page()->selectedText(), QString("This is a text")); // Deselect text by mouse click QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, view.geometry().center()); - QVERIFY(selectionChangedSpy.wait()); - QCOMPARE(selectionChangedSpy.size(), 2); + QTRY_COMPARE(selectionChangedSpy.size(), 2); QVERIFY(!view.hasSelection()); QVERIFY(view.page()->selectedText().isEmpty()); // Select text by ctrl+a QTest::keyClick(view.windowHandle(), Qt::Key_A, Qt::ControlModifier); - QVERIFY(selectionChangedSpy.wait()); - QCOMPARE(selectionChangedSpy.size(), 3); + QTRY_COMPARE(selectionChangedSpy.size(), 3); QVERIFY(view.hasSelection()); QCOMPARE(view.page()->selectedText(), QString("This is a text")); @@ -2332,8 +2334,7 @@ void tst_QWebEngineView::textSelectionOutOfInputField() view.hide(); view.page()->setLifecycleState(QWebEnginePage::LifecycleState::Discarded); view.show(); - QVERIFY(loadFinishedSpy.wait()); - QCOMPARE(selectionChangedSpy.size(), 4); + QTRY_COMPARE(selectionChangedSpy.size(), 4); QVERIFY(!view.hasSelection()); QVERIFY(view.page()->selectedText().isEmpty()); @@ -2356,31 +2357,27 @@ void tst_QWebEngineView::textSelectionOutOfInputField() // Select the whole page by ctrl+a QTest::keyClick(view.windowHandle(), Qt::Key_A, Qt::ControlModifier); - QVERIFY(selectionChangedSpy.wait()); - QCOMPARE(selectionChangedSpy.size(), 1); + QTRY_COMPARE(selectionChangedSpy.size(), 1); QVERIFY(view.hasSelection()); QVERIFY(view.page()->selectedText().startsWith(QString("This is a text"))); // Remove selection by clicking into an input field QPoint textInputCenter = elementCenter(view.page(), "input1"); QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter); - QVERIFY(selectionChangedSpy.wait()); + QTRY_COMPARE(selectionChangedSpy.size(), 2); QCOMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1")); - QCOMPARE(selectionChangedSpy.size(), 2); QVERIFY(!view.hasSelection()); QVERIFY(view.page()->selectedText().isEmpty()); // Select the content of the input field by ctrl+a QTest::keyClick(view.windowHandle(), Qt::Key_A, Qt::ControlModifier); - QVERIFY(selectionChangedSpy.wait()); - QCOMPARE(selectionChangedSpy.size(), 3); + QTRY_COMPARE(selectionChangedSpy.size(), 3); QVERIFY(view.hasSelection()); QCOMPARE(view.page()->selectedText(), QString("QtWebEngine")); // Deselect input field's text by mouse click QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, view.geometry().center()); - QVERIFY(selectionChangedSpy.wait()); - QCOMPARE(selectionChangedSpy.size(), 4); + QTRY_COMPARE(selectionChangedSpy.size(), 4); QVERIFY(!view.hasSelection()); QVERIFY(view.page()->selectedText().isEmpty()); } @@ -2959,6 +2956,7 @@ void tst_QWebEngineView::imeCompositionQueryEvent() } QInputMethodQueryEvent srrndTextQuery(Qt::ImSurroundingText); + QInputMethodQueryEvent absolutePosQuery(Qt::ImAbsolutePosition); QInputMethodQueryEvent cursorPosQuery(Qt::ImCursorPosition); QInputMethodQueryEvent anchorPosQuery(Qt::ImAnchorPosition); @@ -2973,11 +2971,13 @@ void tst_QWebEngineView::imeCompositionQueryEvent() QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 11); QApplication::sendEvent(input, &srrndTextQuery); + QApplication::sendEvent(input, &absolutePosQuery); QApplication::sendEvent(input, &cursorPosQuery); QApplication::sendEvent(input, &anchorPosQuery); qApp->processEvents(); QTRY_COMPARE(srrndTextQuery.value(Qt::ImSurroundingText).toString(), QString("")); + QTRY_COMPARE(absolutePosQuery.value(Qt::ImAbsolutePosition).toInt(), 11); QTRY_COMPARE(cursorPosQuery.value(Qt::ImCursorPosition).toInt(), 11); QTRY_COMPARE(anchorPosQuery.value(Qt::ImAnchorPosition).toInt(), 11); @@ -2993,11 +2993,13 @@ void tst_QWebEngineView::imeCompositionQueryEvent() QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("composition")); QApplication::sendEvent(input, &srrndTextQuery); + QApplication::sendEvent(input, &absolutePosQuery); QApplication::sendEvent(input, &cursorPosQuery); QApplication::sendEvent(input, &anchorPosQuery); qApp->processEvents(); QTRY_COMPARE(srrndTextQuery.value(Qt::ImSurroundingText).toString(), QString("composition")); + QTRY_COMPARE(absolutePosQuery.value(Qt::ImAbsolutePosition).toInt(), 11); QTRY_COMPARE(cursorPosQuery.value(Qt::ImCursorPosition).toInt(), 11); QTRY_COMPARE(anchorPosQuery.value(Qt::ImAnchorPosition).toInt(), 11); } @@ -3785,5 +3787,49 @@ void tst_QWebEngineView::datalist() QStringLiteral("fil")); } +class ConsolePage : public QWebEnginePage +{ + Q_OBJECT +public: + ConsolePage(QObject *parent = nullptr) : QWebEnginePage(parent) { } + void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, + int lineNumber, const QString &sourceID) override + { + Q_UNUSED(level) + Q_UNUSED(lineNumber) + Q_UNUSED(sourceID) + if (message.contains("TEST_KEY:Shift")) + emit done(); + } +signals: + void done(); +}; + +//qtbug_113704 +void tst_QWebEngineView::longKeyEventText() +{ + const QString html(QStringLiteral("<html><body><p>TEST</p>" + "<script>" + "document.addEventListener('keydown', (event)=> {" + "console.log('TEST_KEY:' + event.key);" + "});" + "</script>" + "</body></html>")); + + QWebEngineView view; + ConsolePage page; + view.setPage(&page); + QSignalSpy loadFinishedSpy(view.page(), &QWebEnginePage::loadFinished); + view.resize(200, 400); + view.show(); + view.setHtml(html); + QTRY_VERIFY(loadFinishedSpy.size()); + QSignalSpy consoleMessageSpy(&page, &ConsolePage::done); + Qt::Key key(Qt::Key_Shift); + QKeyEvent event(QKeyEvent::KeyPress, key, Qt::NoModifier, QKeySequence(key).toString()); + QApplication::sendEvent(view.focusProxy(), &event); + QTRY_VERIFY(consoleMessageSpy.size()); +} + QTEST_MAIN(tst_QWebEngineView) #include "tst_qwebengineview.moc" diff --git a/tests/auto/widgets/touchinput/tst_touchinput.cpp b/tests/auto/widgets/touchinput/tst_touchinput.cpp index 562ccfcef..de3712370 100644 --- a/tests/auto/widgets/touchinput/tst_touchinput.cpp +++ b/tests/auto/widgets/touchinput/tst_touchinput.cpp @@ -130,7 +130,7 @@ void TouchInputTest::initTestCase() view.setHtml("<html><head><style>.rect { min-width: 240px; min-height: 120px; }</style></head><body>" "<p id='text' style='width: 150px;'>The Qt Company</p>" "<div id='notext' style='width: 150px; height: 100px; background-color: #f00;'></div>" - "<form><input id='input' width='150px' type='text' value='The Qt Company2' /></form>" + "<form><input id='input' style='width: 150px;' type='text' value='The Qt Company2' /></form>" "<button id='btn' type='button' onclick='alert(\"button clicked!\")'>Click Me!</button>" "<select id='select' onchange='alert(\"option changed to: \" + this.value)'>" "<option value='O1'>O1</option><option value='O2'>O2</option><option value='O3'>O3</option></select>" |