forked from pool/libqt5-qtwebengine
b836a597c6
- Fix a deadlock causing audio/video playback to fail (boo#1163744): * QTBUG-82186.patch - Fix an issue with selections breaking replying in KMail: * QTBUG-81574.patch OBS-URL: https://build.opensuse.org/request/show/777988 OBS-URL: https://build.opensuse.org/package/show/KDE:Qt:5.14/libqt5-qtwebengine?expand=0&rev=12
198 lines
7.6 KiB
Diff
198 lines
7.6 KiB
Diff
From 7d56bbb4c1708f00f729bdfe2e8951c644c83194 Mon Sep 17 00:00:00 2001
|
|
From: Kirill Burtsev <kirill.burtsev@qt.io>
|
|
Date: Wed, 12 Feb 2020 16:15:34 +0100
|
|
Subject: [PATCH] Clear previous page text selection on new navigation unconditionally
|
|
|
|
Remove code duplication on triggering new url load, and use direct
|
|
code to clear SelectedText instead of CollapseSelection as it assumes
|
|
focused frame and might be ignored.
|
|
|
|
Fixes: QTBUG-81574
|
|
Change-Id: I01cf02967e118f407c8a3997e176d5b258478a5a
|
|
---
|
|
|
|
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
|
|
index 8cc8179..a7579f9 100644
|
|
--- a/src/core/web_contents_adapter.cpp
|
|
+++ b/src/core/web_contents_adapter.cpp
|
|
@@ -67,6 +67,7 @@
|
|
#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
|
|
#include "base/values.h"
|
|
#include "content/browser/renderer_host/render_view_host_impl.h"
|
|
+#include "content/browser/renderer_host/text_input_manager.h"
|
|
#include "content/browser/web_contents/web_contents_impl.h"
|
|
#include "content/public/browser/browser_task_traits.h"
|
|
#include "content/public/browser/child_process_security_policy.h"
|
|
@@ -369,6 +370,23 @@
|
|
}
|
|
}
|
|
|
|
+static void Navigate(WebContentsAdapter *adapter, const content::NavigationController::LoadURLParams ¶ms)
|
|
+{
|
|
+ Q_ASSERT(adapter);
|
|
+ adapter->webContents()->GetController().LoadURLWithParams(params);
|
|
+ adapter->focusIfNecessary();
|
|
+ adapter->resetSelection();
|
|
+}
|
|
+
|
|
+static void NavigateTask(QWeakPointer<WebContentsAdapter> weakAdapter, const content::NavigationController::LoadURLParams ¶ms)
|
|
+{
|
|
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
|
+ const auto adapter = weakAdapter.toStrongRef();
|
|
+ if (!adapter)
|
|
+ return;
|
|
+ Navigate(adapter.get(), params);
|
|
+}
|
|
+
|
|
namespace {
|
|
static QList<WebContentsAdapter *> recursive_guard_loading_adapters;
|
|
|
|
@@ -705,21 +723,12 @@
|
|
}
|
|
}
|
|
|
|
- auto navigate = [](QWeakPointer<WebContentsAdapter> weakAdapter, const content::NavigationController::LoadURLParams ¶ms) {
|
|
- const auto adapter = weakAdapter.toStrongRef();
|
|
- if (!adapter)
|
|
- return;
|
|
- adapter->webContents()->GetController().LoadURLWithParams(params);
|
|
- adapter->focusIfNecessary();
|
|
- };
|
|
-
|
|
- QWeakPointer<WebContentsAdapter> weakThis(sharedFromThis());
|
|
if (resizeNeeded) {
|
|
// Schedule navigation on the event loop.
|
|
base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
|
|
- base::BindOnce(navigate, std::move(weakThis), std::move(params)));
|
|
+ base::BindOnce(&NavigateTask, sharedFromThis().toWeakRef(), std::move(params)));
|
|
} else {
|
|
- navigate(std::move(weakThis), params);
|
|
+ Navigate(this, params);
|
|
}
|
|
}
|
|
|
|
@@ -752,9 +761,7 @@
|
|
params.can_load_local_resources = true;
|
|
params.transition_type = ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_API);
|
|
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
|
|
- m_webContents->GetController().LoadURLWithParams(params);
|
|
- focusIfNecessary();
|
|
- m_webContents->CollapseSelection();
|
|
+ Navigate(this, params);
|
|
}
|
|
|
|
void WebContentsAdapter::save(const QString &filePath, int savePageFormat)
|
|
@@ -1676,6 +1683,17 @@
|
|
return m_webContents->GetFocusedFrame() != nullptr;
|
|
}
|
|
|
|
+void WebContentsAdapter::resetSelection()
|
|
+{
|
|
+ CHECK_INITIALIZED();
|
|
+ // unconditionally clears the selection in contrast to CollapseSelection, which checks focus state first
|
|
+ if (auto rwhv = static_cast<RenderWidgetHostViewQt *>(m_webContents->GetRenderWidgetHostView())) {
|
|
+ if (auto mgr = rwhv->GetTextInputManager())
|
|
+ if (auto selection = const_cast<content::TextInputManager::TextSelection *>(mgr->GetTextSelection(rwhv)))
|
|
+ selection->SetSelection(base::string16(), 0, gfx::Range(), false);
|
|
+ }
|
|
+}
|
|
+
|
|
WebContentsAdapterClient::RenderProcessTerminationStatus
|
|
WebContentsAdapterClient::renderProcessExitStatus(int terminationStatus) {
|
|
auto status = WebContentsAdapterClient::RenderProcessTerminationStatus(-1);
|
|
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
|
|
index 11f8f9c..f8f147f 100644
|
|
--- a/src/core/web_contents_adapter.h
|
|
+++ b/src/core/web_contents_adapter.h
|
|
@@ -229,6 +229,7 @@
|
|
void focusIfNecessary();
|
|
bool isFindTextInProgress() const;
|
|
bool hasFocusedFrame() const;
|
|
+ void resetSelection();
|
|
|
|
// meant to be used within WebEngineCore only
|
|
void initialize(content::SiteInstance *site);
|
|
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
|
|
index 8cdcc9f..94b3f16 100644
|
|
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
|
|
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
|
|
@@ -700,7 +700,7 @@
|
|
CursorTrackedPage(QWidget *parent = 0): QWebEnginePage(parent) {
|
|
}
|
|
|
|
- QString selectedText() {
|
|
+ QString jsSelectedText() {
|
|
return evaluateJavaScriptSync(this, "window.getSelection().toString()").toString();
|
|
}
|
|
|
|
@@ -716,42 +716,52 @@
|
|
int isSelectionCollapsed() {
|
|
return evaluateJavaScriptSync(this, "window.getSelection().getRangeAt(0).collapsed").toBool();
|
|
}
|
|
- bool hasSelection()
|
|
- {
|
|
- return !selectedText().isEmpty();
|
|
- }
|
|
};
|
|
|
|
void tst_QWebEnginePage::textSelection()
|
|
{
|
|
- QWebEngineView view;
|
|
- CursorTrackedPage *page = new CursorTrackedPage(&view);
|
|
- QString content("<html><body><p id=one>The quick brown fox</p>" \
|
|
+ CursorTrackedPage page;
|
|
+
|
|
+ QString textToSelect("The quick brown fox");
|
|
+ QString content = QString("<html><body><p id=one>%1</p>" \
|
|
"<p id=two>jumps over the lazy dog</p>" \
|
|
- "<p>May the source<br/>be with you!</p></body></html>");
|
|
- page->setView(&view);
|
|
- QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
|
|
- page->setHtml(content);
|
|
+ "<p>May the source<br/>be with you!</p></body></html>").arg(textToSelect);
|
|
+
|
|
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
|
|
+ page.setHtml(content);
|
|
QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
|
|
|
|
// these actions must exist
|
|
- QVERIFY(page->action(QWebEnginePage::SelectAll) != 0);
|
|
+ QVERIFY(page.action(QWebEnginePage::SelectAll) != 0);
|
|
|
|
// ..but SelectAll is disabled because the page has no focus due to disabled FocusOnNavigationEnabled.
|
|
- QCOMPARE(page->action(QWebEnginePage::SelectAll)->isEnabled(), false);
|
|
+ QCOMPARE(page.action(QWebEnginePage::SelectAll)->isEnabled(), false);
|
|
|
|
// Verify hasSelection returns false since there is no selection yet...
|
|
- QCOMPARE(page->hasSelection(), false);
|
|
+ QVERIFY(!page.hasSelection());
|
|
+ QVERIFY(page.jsSelectedText().isEmpty());
|
|
|
|
// this will select the first paragraph
|
|
QString selectScript = "var range = document.createRange(); " \
|
|
"var node = document.getElementById(\"one\"); " \
|
|
"range.selectNode(node); " \
|
|
"getSelection().addRange(range);";
|
|
- evaluateJavaScriptSync(page, selectScript);
|
|
- QCOMPARE(page->selectedText().trimmed(), QString::fromLatin1("The quick brown fox"));
|
|
+ evaluateJavaScriptSync(&page, selectScript);
|
|
+
|
|
// Make sure hasSelection returns true, since there is selected text now...
|
|
- QCOMPARE(page->hasSelection(), true);
|
|
+ QTRY_VERIFY(page.hasSelection());
|
|
+ QCOMPARE(page.selectedText().trimmed(), textToSelect);
|
|
+
|
|
+ QCOMPARE(page.jsSelectedText().trimmed(), textToSelect);
|
|
+
|
|
+ // navigate away and check that selection is cleared
|
|
+ page.load(QUrl("about:blank"));
|
|
+ QTRY_COMPARE(loadSpy.count(), 2);
|
|
+
|
|
+ QVERIFY(!page.hasSelection());
|
|
+ QVERIFY(page.selectedText().isEmpty());
|
|
+
|
|
+ QVERIFY(page.jsSelectedText().isEmpty());
|
|
}
|
|
|
|
|