diff options
author | Peter Varga <pvarga@inf.u-szeged.hu> | 2017-04-27 11:29:46 +0200 |
---|---|---|
committer | Peter Varga <pvarga@inf.u-szeged.hu> | 2017-07-20 00:23:45 +0000 |
commit | 54e108f1efbc695a8da2f3ce33a44cff2eae4a36 (patch) | |
tree | fcd2d8155ec09e5b50e8dd905ff8f768751a7fb0 | |
parent | 4ea9d5158336313b14a7ca7223371ccd4550706c (diff) |
Fix emitting selectionChanged signal for non-user text selection change
This fixes the case when the text selection is triggered by JavaScript.
Text selection changes triggered by IME composition text replecement are
ignored. Test has been added for mouse selection clipboard: non-user
text selection should not update the clipboard.
Pulls in Chromium changes:
3deea95 Update TextSelection for non-user initiated events
Task-number: QTBUG-53134
Task-number: QTBUG-60381
Change-Id: Ib94f57a2aa61248fba75f595245fb388b9609b6c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
m--------- | src/3rdparty | 0 | ||||
-rw-r--r-- | src/core/render_widget_host_view_qt.cpp | 25 | ||||
-rw-r--r-- | tests/auto/widgets/qwebengineview/BLACKLIST | 3 | ||||
-rw-r--r-- | tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp | 92 |
4 files changed, 77 insertions, 43 deletions
diff --git a/src/3rdparty b/src/3rdparty -Subproject dfaf1564283dcdd222be9717a1a5ad9389ec7f1 +Subproject 3deea958f1485b50940e7437c0a3b73ed29ee13 diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 4e98a1016..f90a44044 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -757,8 +757,12 @@ void RenderWidgetHostViewQt::OnTextSelectionChanged(content::TextInputManager *t Q_UNUSED(text_input_manager); Q_UNUSED(updated_view); + const content::TextInputManager::TextSelection *selection = GetTextInputManager()->GetTextSelection(updated_view); + if (!selection) + return; + #if defined(USE_X11) - if (!GetSelectedText().empty()) { + if (!GetSelectedText().empty() && selection->user_initiated()) { // Set the CLIPBOARD_TYPE_SELECTION to the ui::Clipboard. ui::ScopedClipboardWriter clipboard_writer(ui::CLIPBOARD_TYPE_SELECTION); clipboard_writer.WriteText(GetSelectedText()); @@ -793,6 +797,18 @@ void RenderWidgetHostViewQt::selectionChanged() return; } + if (GetSelectedText().empty()) { + m_anchorPositionWithinSelection = m_cursorPosition; + m_cursorPositionWithinSelection = m_cursorPosition; + + if (!m_emptyPreviousSelection) { + m_emptyPreviousSelection = GetSelectedText().empty(); + m_adapterClient->selectionChanged(); + } + + return; + } + const content::TextInputManager::TextSelection *selection = text_input_manager_->GetTextSelection(); if (!selection) return; @@ -800,13 +816,6 @@ void RenderWidgetHostViewQt::selectionChanged() if (!selection->range().IsValid()) return; - // Avoid duplicate empty selectionChanged() signals - if (GetSelectedText().empty() && m_emptyPreviousSelection) { - m_anchorPositionWithinSelection = m_cursorPosition; - m_cursorPositionWithinSelection = m_cursorPosition; - return; - } - int newAnchorPositionWithinSelection = 0; int newCursorPositionWithinSelection = 0; diff --git a/tests/auto/widgets/qwebengineview/BLACKLIST b/tests/auto/widgets/qwebengineview/BLACKLIST index b3f393af4..a2ecd05b7 100644 --- a/tests/auto/widgets/qwebengineview/BLACKLIST +++ b/tests/auto/widgets/qwebengineview/BLACKLIST @@ -1,8 +1,5 @@ [doNotSendMouseKeyboardEventsWhenDisabled] windows -[imeComposition] -osx - [inputFieldOverridesShortcuts] osx diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index 8509e9a2d..0b49bd892 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -33,6 +33,7 @@ #include <qdiriterator.h> #include <qstackedlayout.h> #include <qtemporarydir.h> +#include <QClipboard> #include <QCompleter> #include <QLineEdit> #include <QHBoxLayout> @@ -145,6 +146,9 @@ private Q_SLOTS: void imeCompositionQueryEvent_data(); void imeCompositionQueryEvent(); void newlineInTextarea(); +#ifndef QT_NO_CLIPBOARD + void globalMouseSelection(); +#endif }; // This will be called before the first test function is executed. @@ -1616,14 +1620,17 @@ void tst_QWebEngineView::textSelectionInInputField() event.setCommitString("XXX", 0, 0); QApplication::sendEvent(view.focusProxy(), &event); QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngineXXX")); + QCOMPARE(selectionChangedSpy.count(), 0); event.setCommitString(QString(), -2, 2); // Erase two characters. QApplication::sendEvent(view.focusProxy(), &event); QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngineX")); + QCOMPARE(selectionChangedSpy.count(), 0); event.setCommitString(QString(), -1, 1); // Erase one character. QApplication::sendEvent(view.focusProxy(), &event); QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngine")); + QCOMPARE(selectionChangedSpy.count(), 0); // Move to the start of the line QTest::keyClick(view.focusProxy(), Qt::Key_Home); @@ -1793,12 +1800,7 @@ void tst_QWebEngineView::emptyInputMethodEvent() QVERIFY(loadFinishedSpy.wait()); evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.focus(); inputEle.select();"); - QTRY_VERIFY(!evaluateJavaScriptSync(view.page(), "window.getSelection().toString()").toString().isEmpty()); - - QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue); - QVERIFY(selectionChangedSpy.wait(100)); - QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue); - QCOMPARE(selectionChangedSpy.count(), 1); + QTRY_COMPARE(selectionChangedSpy.count(), 1); // 1. Empty input method event does not clear text QInputMethodEvent emptyEvent; @@ -1845,12 +1847,7 @@ void tst_QWebEngineView::imeComposition() QVERIFY(loadFinishedSpy.wait()); evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.focus(); inputEle.select();"); - QTRY_VERIFY(!evaluateJavaScriptSync(view.page(), "window.getSelection().toString()").toString().isEmpty()); - - QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue); - QVERIFY(selectionChangedSpy.wait(100)); - QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue); - QCOMPARE(selectionChangedSpy.count(), 1); + QTRY_COMPARE(selectionChangedSpy.count(), 1); // Clear the selection, also cancel the ongoing composition if there is one. { @@ -1859,17 +1856,13 @@ void tst_QWebEngineView::imeComposition() attributes.append(newSelection); QInputMethodEvent event("", attributes); QApplication::sendEvent(view.focusProxy(), &event); - QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "window.getSelection().toString()").toString().isEmpty()); - - QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue); - QVERIFY(selectionChangedSpy.wait(100)); - QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue); + selectionChangedSpy.wait(); QCOMPARE(selectionChangedSpy.count(), 2); } - QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngine inputMethod")); - QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 0); - QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 0); - QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString("")); + QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngine inputMethod")); + QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 0); + QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 0); + QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString("")); selectionChangedSpy.clear(); @@ -1990,19 +1983,14 @@ void tst_QWebEngineView::imeComposition() QList<QInputMethodEvent::Attribute> attributes; QInputMethodEvent event("w", attributes); QApplication::sendEvent(view.focusProxy(), &event); - QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "window.getSelection().toString()").toString().isEmpty()); - QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), QString("oeQtWebEngine w")); - - QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue); - QVERIFY(selectionChangedSpy.wait(100)); - QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue); + // The new composition should clear the previous selection + QVERIFY(selectionChangedSpy.wait()); QCOMPARE(selectionChangedSpy.count(), 2); } - QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("oeQtWebEngine ")); - QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 14); - QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue); - QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 14); - QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue); + QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("oeQtWebEngine ")); + // The cursor should be positioned at the end of the composition text + QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 15); + QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 15); QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString("")); // Send commit text, which makes the editor conforms composition. @@ -2017,6 +2005,7 @@ void tst_QWebEngineView::imeComposition() QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 15); QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 15); QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString("")); + QCOMPARE(selectionChangedSpy.count(), 2); } void tst_QWebEngineView::newlineInTextarea() @@ -2196,5 +2185,44 @@ void tst_QWebEngineView::imeCompositionQueryEvent() QTRY_COMPARE(anchorPosQuery.value(Qt::ImAnchorPosition).toInt(), 11); } +#ifndef QT_NO_CLIPBOARD +void tst_QWebEngineView::globalMouseSelection() +{ + if (!QApplication::clipboard()->supportsSelection()) { + QSKIP("Test only relevant for systems with selection"); + return; + } + + QApplication::clipboard()->clear(QClipboard::Selection); + QWebEngineView view; + view.show(); + + QSignalSpy selectionChangedSpy(&view, SIGNAL(selectionChanged())); + QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool))); + view.setHtml("<html><body>" + " <input type='text' id='input1' value='QtWebEngine' size='50' />" + "</body></html>"); + QVERIFY(loadFinishedSpy.wait()); + + // Select text via JavaScript + evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.focus(); inputEle.select();"); + QTRY_COMPARE(selectionChangedSpy.count(), 1); + QVERIFY(QApplication::clipboard()->text(QClipboard::Selection).isEmpty()); + + // Deselect the selection (this moves the current cursor to the end of the text) + QPoint textInputCenter = elementCenter(view.page(), "input1"); + QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter); + QVERIFY(selectionChangedSpy.wait()); + QCOMPARE(selectionChangedSpy.count(), 2); + QVERIFY(QApplication::clipboard()->text(QClipboard::Selection).isEmpty()); + + // Select to the start of the line + QTest::keyClick(view.focusProxy(), Qt::Key_Home, Qt::ShiftModifier); + QVERIFY(selectionChangedSpy.wait()); + QCOMPARE(selectionChangedSpy.count(), 3); + QCOMPARE(QApplication::clipboard()->text(QClipboard::Selection), QStringLiteral("QtWebEngine")); +} +#endif + QTEST_MAIN(tst_QWebEngineView) #include "tst_qwebengineview.moc" |