diff --git a/src/3rdparty b/src/3rdparty index dfaf1564283dcdd222be9717a1a5ad9389ec7f1b..3deea958f1485b50940e7437c0a3b73ed29ee134 160000 --- a/src/3rdparty +++ b/src/3rdparty @@ -1 +1 @@ -Subproject commit dfaf1564283dcdd222be9717a1a5ad9389ec7f1b +Subproject commit 3deea958f1485b50940e7437c0a3b73ed29ee134 diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 4e98a1016685ea8c6c2fd98cfdc469fa66d24654..f90a440449c0d9ef0746dc465550ac092d63dee4 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 b3f393af46c5430fed49549e953a8638bde24277..a2ecd05b724edc04c208a57ec5199008ff8fee1c 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 8509e9a2ddbea3dd4b7e2805625100f3c4ddb0e7..0b49bd89250169806a1dc47e5772a3e6b49d6a04 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"