File QTBUG-81574.patch of Package libqt5-qtwebengine

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

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
@@ -65,6 +65,7 @@
 #include "base/run_loop.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/child_process_security_policy.h"
 #include "content/public/browser/devtools_agent_host.h"
@@ -661,6 +662,7 @@
         // Follow chrome::Navigate and invalidate the URL immediately.
         adapter->m_webContentsDelegate->NavigationStateChanged(adapter->webContents(), content::INVALIDATE_TYPE_URL);
         adapter->focusIfNecessary();
+        adapter->resetSelection();
     };
 
     QWeakPointer<WebContentsAdapter> weakThis(sharedFromThis());
@@ -702,7 +704,7 @@
     params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
     m_webContents->GetController().LoadURLWithParams(params);
     focusIfNecessary();
-    m_webContents->CollapseSelection();
+    resetSelection();
 }
 
 void WebContentsAdapter::save(const QString &filePath, int savePageFormat)
@@ -1614,6 +1621,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
@@ -879,7 +879,7 @@
     CursorTrackedPage(QWidget *parent = 0): QWebEnginePage(parent) {
     }
 
-    QString selectedText() {
+    QString jsSelectedText() {
         return evaluateJavaScriptSync(this, "window.getSelection().toString()").toString();
     }
 
@@ -895,10 +895,6 @@
     int isSelectionCollapsed() {
         return evaluateJavaScriptSync(this, "window.getSelection().getRangeAt(0).collapsed").toBool();
     }
-    bool hasSelection()
-    {
-        return !selectedText().isEmpty();
-    }
 };
 
 void tst_QWebEnginePage::cursorMovements()
@@ -1101,18 +1097,19 @@
 
 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(loadSpy.count(), 1);
 
     // these actions must exist
-    QVERIFY(page->action(QWebEnginePage::SelectAll) != 0);
+    QVERIFY(page.action(QWebEnginePage::SelectAll) != 0);
 #if defined(QWEBENGINEPAGE_SELECTACTIONS)
     QVERIFY(page->action(QWebEnginePage::SelectNextChar) != 0);
     QVERIFY(page->action(QWebEnginePage::SelectPreviousChar) != 0);
@@ -1144,25 +1140,38 @@
 #endif
 
     // ..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);
+
 #if defined(QWEBENGINEPAGE_SELECTEDHTML)
     QRegExp regExp(" style=\".*\"");
     regExp.setMinimal(true);
     QCOMPARE(page->selectedHtml().trimmed().replace(regExp, ""), QString::fromLatin1("<p id=\"one\">The quick brown fox</p>"));
 #endif
     // 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());
 
 #if defined(QWEBENGINEPAGE_SELECTACTIONS)
     // here the actions are enabled after a selection has been created
openSUSE Build Service is sponsored by