diff options
author | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2025-01-10 14:45:45 +0200 |
---|---|---|
committer | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2025-01-10 14:45:45 +0200 |
commit | 77c4670a926c461d182db33242edac779f9e44d2 (patch) | |
tree | 4c61f0ba4e88cff411a0560b4602cf74448dca42 | |
parent | 864b08394d1e6d366d7c136ffc50e27adfd08447 (diff) | |
parent | 824be6fd525f415488c6117db8b03e1a90cabf05 (diff) |
Merge tag 'v6.5.4-lts' into 6.5.4v6.5.4-lts-lgpl6.5.4
Qt 6.5.4-lts release
Change-Id: Ie240e184ec34fe43acab017cffd6888ab53aefbe
38 files changed, 302 insertions, 102 deletions
diff --git a/.cmake.conf b/.cmake.conf index 2943a34cc..e710307cd 100644 --- a/.cmake.conf +++ b/.cmake.conf @@ -1,3 +1,3 @@ -set(QT_REPO_MODULE_VERSION "6.5.3") +set(QT_REPO_MODULE_VERSION "6.5.4") set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1") set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_WEBENGINE "3.19") diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION index ea03ba173..21a6b0c46 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: 117.0.5938.63 +Patched with security patches up to Chromium version: 119.0.6045.199 diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake index 73a06d59f..fa05bfbdf 100644 --- a/cmake/Functions.cmake +++ b/cmake/Functions.cmake @@ -918,6 +918,8 @@ macro(append_compiler_linker_sdk_setup) endif() extend_gn_list(gnArgArg ARGS is_clang CONDITION CLANG) + extend_gn_list(gnArgArg ARGS is_msvc CONDITION MSVC) + if(CLANG) if(MACOS) get_darwin_sdk_version(macSdkVersion) @@ -976,7 +978,7 @@ macro(append_compiler_linker_sdk_setup) endif() endif() - if(WIN32) + if(MSVC) get_filename_component(windowsSdkPath $ENV{WINDOWSSDKDIR} ABSOLUTE) get_filename_component(visualStudioPath $ENV{VSINSTALLDIR} ABSOLUTE) list(APPEND gnArgArg diff --git a/configure.cmake b/configure.cmake index c217175b0..83cc0e4c9 100644 --- a/configure.cmake +++ b/configure.cmake @@ -574,19 +574,16 @@ ${xcbErrorMessage}" ) add_check_for_support( MODULES QtWebEngine QtPdf - CONDITION + CONDITION MSVC OR (LINUX AND CMAKE_CXX_COMPILER_ID STREQUAL GNU) OR (LINUX AND CMAKE_CXX_COMPILER_ID STREQUAL Clang) OR - (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL MSVC) OR - (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL Clang AND - CMAKE_CXX_SIMULATE_ID STREQUAL MSVC) OR (MACOS AND CMAKE_CXX_COMPILER_ID STREQUAL AppleClang) OR (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL AppleClang) OR (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) + if(MSVC) add_check_for_support( MODULES QtWebEngine QtPdf CONDITION NOT MSVC_VERSION LESS 1929 diff --git a/dependencies.yaml b/dependencies.yaml index b2ae82c93..b67557c57 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -1,13 +1,13 @@ dependencies: - ../qtdeclarative: - ref: e00c258fa5a4e122636d441967dea035865fac5d + ../tqtc-qtdeclarative: + ref: 533a9a8afcc56635bed5da93102028e01fa708c0 required: true - ../qtpositioning: - ref: e6870f020291ea61d011fc7155816865ec0f02e8 + ../tqtc-qtpositioning: + ref: a619623a4949071ddf7392d26b916890a751e965 required: false - ../qttools: - ref: 3a0c45ad9c86dc1c62384575f69eddc8f3fddf35 + ../tqtc-qttools: + ref: 8be3e6cff9903e7db610c185aad1b598cce0368c required: false - ../qtwebchannel: - ref: 2daf972a3e451065b7a8f11b98f225761795ab28 + ../tqtc-qtwebchannel: + ref: c772de714a2e8dec516c380a222ec58ad92459fc required: false diff --git a/examples/pdf/multipage/doc/src/multipage.qdoc b/examples/pdf/multipage/doc/src/multipage.qdoc index b9fec15a9..fff8b0d11 100644 --- a/examples/pdf/multipage/doc/src/multipage.qdoc +++ b/examples/pdf/multipage/doc/src/multipage.qdoc @@ -5,7 +5,7 @@ \example multipage \meta installpath pdf \ingroup qtpdf-examples - \examplecategory {Graphics & Multimedia} + \examplecategory {User Interface Components} \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 0c9fa06a9..b56958a9f 100644 --- a/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc +++ b/examples/pdfwidgets/pdfviewer/doc/src/pdfviewer.qdoc @@ -5,7 +5,7 @@ \example pdfviewer \meta installpath pdfwidgets \ingroup qtpdf-examples - \examplecategory {Graphics & Multimedia} + \examplecategory {User Interface Components} \title PDF Viewer Widget Example \brief A widget-based PDF viewer that allows scrolling through the pages. diff --git a/src/3rdparty b/src/3rdparty -Subproject ef090c47d08c734ae2b3c1db508982aca0f3ee1 +Subproject 21bb29b9b730cc215ee7dfb3cf343139a9be952 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/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/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp index 53930bc67..78021248c 100644 --- a/src/core/api/qwebenginepage.cpp +++ b/src/core/api/qwebenginepage.cpp @@ -510,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); @@ -1504,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(). @@ -1645,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/api/qwebengineprofile.cpp b/src/core/api/qwebengineprofile.cpp index ab873e345..2defebdaf 100644 --- a/src/core/api/qwebengineprofile.cpp +++ b/src/core/api/qwebengineprofile.cpp @@ -495,7 +495,10 @@ QWebEngineProfile::HttpCacheType QWebEngineProfile::httpCacheType() const /*! Sets the HTTP cache type to \a httpCacheType. - \sa httpCacheType(), setCachePath() + \note Setting the \a httpCacheType to NoCache on the profile, which has already some cache + entries does not trigger the removal of those entries. + + \sa httpCacheType(), setCachePath(), clearHttpCache() */ void QWebEngineProfile::setHttpCacheType(QWebEngineProfile::HttpCacheType httpCacheType) { diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp index 24c006dc5..a2e00cfa1 100644 --- a/src/core/browser_accessibility_qt.cpp +++ b/src/core/browser_accessibility_qt.cpp @@ -25,6 +25,8 @@ public: BrowserAccessibilityQt(content::BrowserAccessibilityManager *manager, ui::AXNode *node); ~BrowserAccessibilityQt(); + bool isReady() const; + QtWebEngineCore::BrowserAccessibilityInterface *interface = nullptr; }; @@ -142,6 +144,16 @@ BrowserAccessibilityQt::~BrowserAccessibilityQt() { if (interface) interface->destroy(); +<<<<<<< HEAD +======= +} + +bool BrowserAccessibilityQt::isReady() const +{ + // FIXME: This is just a workaround, remove this when the commented out assert in + // BrowserAccessibilityManager::GetFromID(int32_t id) gets fixed. + return manager()->GetFromID(node()->id()) != nullptr; +>>>>>>> v6.5.4-lts } BrowserAccessibilityInterface::BrowserAccessibilityInterface(BrowserAccessibilityQt *chromiumInterface) @@ -169,6 +181,9 @@ void BrowserAccessibilityInterface::destroy() bool BrowserAccessibilityInterface::isValid() const { + if (!q->isReady()) + return false; + auto managerQt = static_cast<content::BrowserAccessibilityManagerQt *>(q->manager()); return managerQt && managerQt->isValid(); } @@ -276,6 +291,9 @@ int BrowserAccessibilityInterface::indexOfChild(const QAccessibleInterface *ifac QString BrowserAccessibilityInterface::text(QAccessible::Text t) const { + if (!q->isReady()) + return QString(); + switch (t) { case QAccessible::Name: return toQt(q->GetStringAttribute(ax::mojom::StringAttribute::kName)); @@ -297,7 +315,7 @@ void BrowserAccessibilityInterface::setText(QAccessible::Text t, const QString & QRect BrowserAccessibilityInterface::rect() const { - if (!q->manager()) // needed implicitly by GetScreenBoundsRect() + if (!q->manager() || !q->isReady()) // needed implicitly by GetScreenBoundsRect() return QRect(); gfx::Rect bounds = q->GetUnclippedScreenBoundsRect(); bounds = gfx::ScaleToRoundedRect(bounds, 1.f / q->manager()->device_scale_factor()); // FIXME: check @@ -699,6 +717,11 @@ QAccessible::Role BrowserAccessibilityInterface::role() const QAccessible::State BrowserAccessibilityInterface::state() const { QAccessible::State state = QAccessible::State(); + if (!q->isReady()) { + state.invalid = true; + return state; + } + if (q->HasState(ax::mojom::State::kCollapsed)) state.collapsed = true; if (q->HasState(ax::mojom::State::kDefault)) 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/compositor/compositor.cpp b/src/core/compositor/compositor.cpp index c147f988b..d576e0923 100644 --- a/src/core/compositor/compositor.cpp +++ b/src/core/compositor/compositor.cpp @@ -94,10 +94,8 @@ void Compositor::Observer::unbind() Compositor::Handle<Compositor> Compositor::Observer::compositor() { - if (!m_binding) - return nullptr; g_bindings.lock(); - if (m_binding->compositor) + if (m_binding && m_binding->compositor) return m_binding->compositor; // delay unlock g_bindings.unlock(); return nullptr; @@ -128,10 +126,8 @@ void Compositor::unbind() Compositor::Handle<Compositor::Observer> Compositor::observer() { - if (!m_binding) - return nullptr; g_bindings.lock(); - if (m_binding->observer) + if (m_binding && m_binding->observer) return m_binding->observer; // delay unlock g_bindings.unlock(); return nullptr; diff --git a/src/core/doc/qtwebengine.qdocconf b/src/core/doc/qtwebengine.qdocconf index 5cbe9e500..d322cc285 100644 --- a/src/core/doc/qtwebengine.qdocconf +++ b/src/core/doc/qtwebengine.qdocconf @@ -31,7 +31,8 @@ qhp.QtWebEngine.subprojects.examples.selectors = doc:example qhp.QtWebEngine.subprojects.examples.sortPages = true manifestmeta.highlighted.names += "QtWebEngine/WebEngine Widgets Simple Browser Example" \ - "QtWebEngine/WebEngine Quick Nano Browser" + "QtWebEngine/WebEngine Quick Nano Browser" \ + "QtWebEngine/Recipe Browser" tagfile = ../../../doc/qtwebengine/qtwebengine.tags 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 11de95d44..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. 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/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_adapter.cpp b/src/core/profile_adapter.cpp index e9e9aaeda..4ed45c020 100644 --- a/src/core/profile_adapter.cpp +++ b/src/core/profile_adapter.cpp @@ -345,8 +345,6 @@ void ProfileAdapter::setHttpCacheType(ProfileAdapter::HttpCacheType newhttpCache return; if (!m_offTheRecord && !m_profile->m_profileIOData->isClearHttpCacheInProgress()) { m_profile->m_profileIOData->resetNetworkContext(); - if (m_httpCacheType == NoCache) - clearHttpCache(); } } diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 37f3b13ac..83066e811 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -210,10 +210,28 @@ static std::unique_ptr<content::WebContents> createBlankWebContents(WebContentsA return webContents; } +static int navigationListSize(content::NavigationController &controller) { + // If we're currently on the initial NavigationEntry, no navigation has + // committed, so the initial NavigationEntry should not be part of the + // "Navigation List", and we should return 0 as the navigation list size. + if (controller.GetLastCommittedEntry()->IsInitialEntry()) + return 0; + return controller.GetEntryCount(); +} + +static int navigationListCurrentIndex(content::NavigationController &controller) { + // If we're currently on the initial NavigationEntry, no navigation has + // committed, so the initial NavigationEntry should not be part of the + // "Navigation List", and we should return -1 as the current index. + if (controller.GetLastCommittedEntry()->IsInitialEntry()) + return -1; + return controller.GetCurrentEntryIndex(); +} + static void serializeNavigationHistory(content::NavigationController &controller, QDataStream &output) { - const int currentIndex = controller.GetCurrentEntryIndex(); - const int count = controller.GetEntryCount(); + const int currentIndex = navigationListCurrentIndex(controller); + const int count = navigationListSize(controller); const int pendingIndex = controller.GetPendingEntryIndex(); output << kHistoryStreamVersion; @@ -535,6 +553,8 @@ void WebContentsAdapter::initializeRenderPrefs() ? blink::kWebRTCIPHandlingDefaultPublicInterfaceOnly : blink::kWebRTCIPHandlingDefault; #endif + rendererPrefs->can_accept_load_drops = m_adapterClient->webEngineSettings()->testAttribute(QWebEngineSettings::NavigateOnDropEnabled); + // Set web-contents font settings to the default font settings as Chromium constantly overrides // the global font defaults with the font settings of the latest web-contents created. static const gfx::FontRenderParams params = gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr); @@ -909,13 +929,13 @@ void WebContentsAdapter::navigateToOffset(int offset) int WebContentsAdapter::navigationEntryCount() { CHECK_INITIALIZED(0); - return m_webContents->GetController().GetEntryCount(); + return navigationListSize(m_webContents->GetController()); } int WebContentsAdapter::currentNavigationEntryIndex() { CHECK_INITIALIZED(0); - return m_webContents->GetController().GetCurrentEntryIndex(); + return navigationListCurrentIndex(m_webContents->GetController()); } QUrl WebContentsAdapter::getNavigationEntryOriginalUrl(int index) diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 973da88a7..70b1a77b0 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -720,6 +720,9 @@ WebEngineContext::WebEngineContext() enableFeatures.push_back(features::kNetworkServiceInProcess.name); enableFeatures.push_back(features::kTracingServiceInProcess.name); +#if QT_CONFIG(webengine_webrtc_pipewire) + enableFeatures.push_back(features::kWebRtcPipeWireCapturer.name); +#endif // When enabled, event.movement is calculated in blink instead of in browser. disableFeatures.push_back(features::kConsolidatedMovementXY.name); @@ -971,7 +974,7 @@ const char *qWebEngineChromiumVersion() noexcept const char *qWebEngineChromiumSecurityPatchVersion() noexcept { - return "117.0.5938.63"; // FIXME: Remember to update + return "119.0.6045.199"; // FIXME: Remember to update } QT_END_NAMESPACE diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp index 906f9fb72..520bc6499 100644 --- a/src/core/web_engine_settings.cpp +++ b/src/core/web_engine_settings.cpp @@ -441,6 +441,11 @@ bool WebEngineSettings::applySettingsToRendererPreferences(blink::RendererPrefer } } #endif + bool canNavigateOnDrop = testAttribute(QWebEngineSettings::NavigateOnDropEnabled); + if (canNavigateOnDrop != prefs->can_accept_load_drops) { + prefs->can_accept_load_drops = canNavigateOnDrop; + changed = true; + } return changed; } diff --git a/src/pdf/configure/BUILD.root.gn.in b/src/pdf/configure/BUILD.root.gn.in index 3918c1e9f..333e541ab 100644 --- a/src/pdf/configure/BUILD.root.gn.in +++ b/src/pdf/configure/BUILD.root.gn.in @@ -59,7 +59,7 @@ static_library("QtPdf") { deps = [ "//third_party/pdfium" ] - if (is_win) { + if (is_msvc) { libs = [ "dloadhelper.lib", "winmm.lib", 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/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/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/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/data/tst_filePicker.qml b/tests/auto/quick/qmltests/data/tst_filePicker.qml index 2d6a88703..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 @@ -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 @@ -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/qwebenginehistory/tst_qwebenginehistory.cpp b/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp index 6ddc031d5..ad66e972c 100644 --- a/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp +++ b/tests/auto/widgets/qwebenginehistory/tst_qwebenginehistory.cpp @@ -487,9 +487,9 @@ void tst_QWebEngineHistory::clear() QWebEnginePage page2(this); QWebEngineHistory* hist2 = page2.history(); - QCOMPARE(hist2->count(), 1); + QCOMPARE(hist2->count(), 0); hist2->clear(); - QCOMPARE(hist2->count(), 1); // Do not change anything. + QCOMPARE(hist2->count(), 0); // Do not change anything. } void tst_QWebEngineHistory::historyItemFromDeletedPage() diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index ba88fd99e..c5d4e2e57 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -278,6 +278,9 @@ private: QWebEngineView* m_view; QWebEnginePage* m_page; + QScopedPointer<QPointingDevice> s_touchDevice = + QScopedPointer<QPointingDevice>(QTest::createTouchDevice()); + QString tmpDirPath() const { static QString tmpd = QDir::tempPath() + "/tst_qwebenginepage-" @@ -285,13 +288,13 @@ private: return tmpd; } - QScopedPointer<QPointingDevice> s_touchDevice; - void makeClick(QWindow *window, bool withTouch = false, const QPoint &p = QPoint()) { + void makeClick(const QPointer<QWindow> window, bool withTouch = false, + const QPoint &p = QPoint()) + { + QVERIFY2(window, "window is gone"); if (!withTouch) { QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), p); } else { - if (!s_touchDevice) - s_touchDevice.reset(QTest::createTouchDevice()); QTest::touchEvent(window, s_touchDevice.get()).press(1, p); QTest::touchEvent(window, s_touchDevice.get()).release(1, p); } @@ -1358,6 +1361,9 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterMove_data() void tst_QWebEnginePage::comboBoxPopupPositionAfterMove() { +#if defined(Q_OS_MACOS) && (defined(__arm64__) || defined(__aarch64__)) + QSKIP("This test crashes for Apple M1"); +#endif QWebEngineView view; view.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft()); view.resize(640, 480); @@ -1370,7 +1376,7 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterMove() QTRY_COMPARE(spyLoadFinished.size(), 1); const auto oldTlws = QGuiApplication::topLevelWindows(); QFETCH(bool, withTouch); - QWindow *window = view.windowHandle(); + QPointer<QWindow> window = view.windowHandle(); auto pos = elementCenter(view.page(), "foo"); makeClick(window, withTouch, pos); QWindow *popup = nullptr; @@ -1420,6 +1426,9 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove_data() void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove() { +#if defined(Q_OS_MACOS) && (defined(__arm64__) || defined(__aarch64__)) + QSKIP("This test crashes for Apple M1"); +#endif QWidget mainWidget; mainWidget.setLayout(new QHBoxLayout); @@ -1443,7 +1452,7 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove() const auto oldTlws = QGuiApplication::topLevelWindows(); QFETCH(bool, withTouch); - QWindow *window = view.window()->windowHandle(); + QPointer<QWindow> window = view.window()->windowHandle(); makeClick(window, withTouch, view.mapTo(view.window(), elementCenter(view.page(), "foo"))); QWindow *popup = nullptr; @@ -2072,14 +2081,14 @@ void tst_QWebEnginePage::symmetricUrl() QVERIFY(view.url().isEmpty()); - QCOMPARE(view.history()->count(), 1); + QCOMPARE(view.history()->count(), 0); QUrl dataUrl("data:text/html,<h1>Test"); view.setUrl(dataUrl); view.show(); QCOMPARE(view.url(), dataUrl); - QCOMPARE(view.history()->count(), 1); + QCOMPARE(view.history()->count(), 0); // loading is _not_ immediate, so the text isn't set just yet. QVERIFY(toPlainTextSync(view.page()).isEmpty()); @@ -2392,7 +2401,7 @@ void tst_QWebEnginePage::setHtmlWithBaseURL() QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 128); // no history item has to be added. - QCOMPARE(m_view->page()->history()->count(), 1); + QCOMPARE(m_view->page()->history()->count(), 0); } class MyPage : public QWebEnginePage @@ -2823,7 +2832,7 @@ void tst_QWebEnginePage::setUrlHistory() int expectedLoadFinishedCount = 0; QSignalSpy spy(m_page, SIGNAL(loadFinished(bool))); - QCOMPARE(m_page->history()->count(), 1); + QCOMPARE(m_page->history()->count(), 0); m_page->setUrl(QUrl()); expectedLoadFinishedCount++; @@ -2897,7 +2906,7 @@ void tst_QWebEnginePage::setUrlUsingStateObject() QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool))); int expectedUrlChangeCount = 0; - QCOMPARE(m_page->history()->count(), 1); + QCOMPARE(m_page->history()->count(), 0); url = QUrl("qrc:/resources/test1.html"); m_page->setUrl(url); @@ -3076,7 +3085,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); } @@ -3722,7 +3731,7 @@ void tst_QWebEnginePage::openLinkInNewPage() QCOMPARE(page1.history()->count(), 1); else QCOMPARE(page1.history()->count(), 2); - QCOMPARE(page2.history()->count(), 1); + QCOMPARE(page2.history()->count(), 0); break; case Effect::LoadInOther: QTRY_COMPARE(page2.spy.size(), 1); diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index a67392801..6dd75a7eb 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -1354,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); @@ -1389,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() @@ -2310,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")); @@ -2333,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()); @@ -2357,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()); } |