From 8eab45ef460cc6614094ec287dda73febdf3e720 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 17 Jan 2017 15:30:11 +0100 Subject: Fix conversion from blink::WebDragOperation to Qt::DropAction blink::WebDragOperation is a bit field, even if it is not used in its blink::WebDragOperationsMask incarnation. In particular, WebDragOperationGeneric can be set in addition to other operations. This fixes situations where UpdateDragCursor is called with multiple bits set in its WebDragOperationArgument and the drag action will be spuriously ignored. Also directly pass the WebDragOperation we get from UpdateDragCursor to chromium's API without converting to QDropAction and then converting it back. Task-number: QTBUG-58037 Change-Id: I5c85699de534771f84db69abf7b98e779872a0f7 Reviewed-by: Allan Sandfeld Jensen --- src/core/web_contents_adapter.cpp | 21 ++++++++++++++++----- src/core/web_contents_adapter.h | 2 +- src/core/web_contents_adapter_p.h | 3 ++- src/core/web_contents_view_qt.cpp | 13 +------------ 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 91e457726..a0aaf8c1e 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -336,7 +336,7 @@ WebContentsAdapterPrivate::WebContentsAdapterPrivate() , adapterClient(0) , nextRequestId(CallbackDirectory::ReservedCallbackIdsEnd) , lastFindRequestId(0) - , currentDropAction(Qt::IgnoreAction) + , currentDropAction(blink::WebDragOperationNone) , inDragUpdateLoop(false) , updateDragCursorMessagePollingTimer(new QTimer) { @@ -1106,7 +1106,7 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD d->currentDropData->file_contents.clear(); d->currentDropData->file_description_filename.clear(); - d->currentDropAction = Qt::IgnoreAction; + d->currentDropAction = blink::WebDragOperationNone; QDrag *drag = new QDrag(dragSource); // will be deleted by Qt's DnD implementation bool dValid = true; QMetaObject::Connection onDestroyed = QObject::connect(dragSource, &QObject::destroyed, [&dValid](){ @@ -1183,6 +1183,17 @@ void WebContentsAdapter::enterDrag(QDragEnterEvent *e, const QPoint &screenPos) flagsFromModifiers(e->keyboardModifiers())); } +Qt::DropAction toQt(blink::WebDragOperation op) +{ + if (op & blink::WebDragOperationCopy) + return Qt::CopyAction; + if (op & blink::WebDragOperationLink) + return Qt::LinkAction; + if (op & blink::WebDragOperationMove || op & blink::WebDragOperationDelete) + return Qt::MoveAction; + return Qt::IgnoreAction; +} + Qt::DropAction WebContentsAdapter::updateDragPosition(QDragMoveEvent *e, const QPoint &screenPos) { Q_D(WebContentsAdapter); @@ -1210,13 +1221,13 @@ Qt::DropAction WebContentsAdapter::updateDragPosition(QDragMoveEvent *e, const Q loop.Run(); d->updateDragCursorMessagePollingTimer->stop(); - return d->currentDropAction; + return toQt(d->currentDropAction); } -void WebContentsAdapter::updateDragAction(Qt::DropAction action) +void WebContentsAdapter::updateDragAction(int action) { Q_D(WebContentsAdapter); - d->currentDropAction = action; + d->currentDropAction = static_cast(action); finishDragUpdate(); } diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h index 3befe6d27..5b2f9a942 100644 --- a/src/core/web_contents_adapter.h +++ b/src/core/web_contents_adapter.h @@ -166,7 +166,7 @@ public: Qt::DropActions allowedActions, const QPixmap &pixmap, const QPoint &offset); void enterDrag(QDragEnterEvent *e, const QPoint &screenPos); Qt::DropAction updateDragPosition(QDragMoveEvent *e, const QPoint &screenPos); - void updateDragAction(Qt::DropAction action); + void updateDragAction(int action); void finishDragUpdate(); void endDragging(const QPoint &clientPos, const QPoint &screenPos); void leaveDrag(); diff --git a/src/core/web_contents_adapter_p.h b/src/core/web_contents_adapter_p.h index 23a1aaef4..2d8490c7b 100644 --- a/src/core/web_contents_adapter_p.h +++ b/src/core/web_contents_adapter_p.h @@ -55,6 +55,7 @@ #include #include "base/memory/ref_counted.h" +#include #include #include @@ -93,7 +94,7 @@ public: quint64 nextRequestId; int lastFindRequestId; std::unique_ptr currentDropData; - Qt::DropAction currentDropAction; + blink::WebDragOperation currentDropAction; bool inDragUpdateLoop; base::Closure dragUpdateLoopQuitClosure; QScopedPointer updateDragCursorMessagePollingTimer; diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp index 0c4cf29d3..24c4e198f 100644 --- a/src/core/web_contents_view_qt.cpp +++ b/src/core/web_contents_view_qt.cpp @@ -203,17 +203,6 @@ Qt::DropActions toQtDropActions(blink::WebDragOperationsMask ops) return result; } -Qt::DropAction toQt(blink::WebDragOperation op) -{ - if (op == blink::WebDragOperationCopy) - return Qt::CopyAction; - if (op == blink::WebDragOperationLink) - return Qt::LinkAction; - if (op == blink::WebDragOperationMove || op == blink::WebDragOperationDelete) - return Qt::MoveAction; - return Qt::IgnoreAction; -} - void WebContentsViewQt::StartDragging(const content::DropData &drop_data, blink::WebDragOperationsMask allowed_ops, const gfx::ImageSkia &image, @@ -235,7 +224,7 @@ void WebContentsViewQt::StartDragging(const content::DropData &drop_data, void WebContentsViewQt::UpdateDragCursor(blink::WebDragOperation dragOperation) { - m_client->webContentsAdapter()->updateDragAction(toQt(dragOperation)); + m_client->webContentsAdapter()->updateDragAction(dragOperation); } void WebContentsViewQt::TakeFocus(bool reverse) -- cgit v1.2.3 From 1dda472b72592aaef365c05365c2907894a35bc6 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 17 Jan 2017 16:41:31 +0100 Subject: Disable Q_ASSERTs for a release build Qt WebEngine uses the core_gyp_generator.pro and the gyp_generator.prf files to extract defines set by Qt. Anyhow, only one core_generated.gyp file is written for debug and release builds, which hence misses the QT_NO_DEBUG define specific to debug builds. Work around this by explicitly adding back the define. Task-number: QTBUG-58103 Change-Id: I8684aa08417efc93878d70817211e9f66623c78c Reviewed-by: Allan Sandfeld Jensen --- src/core/qtwebengine.gypi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/qtwebengine.gypi b/src/core/qtwebengine.gypi index d0ab01534..cd8d9cb5d 100644 --- a/src/core/qtwebengine.gypi +++ b/src/core/qtwebengine.gypi @@ -5,6 +5,11 @@ 'variables': { 'version_script_location%': '<(chromium_src_dir)/build/util/version.py', }, + 'configurations': { + 'Release': { + 'defines': [ 'QT_NO_DEBUG' ], + }, + }, 'dependencies': [ '<(chromium_src_dir)/base/base.gyp:base', '<(chromium_src_dir)/base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', -- cgit v1.2.3 From 2ccbb8d7a22056cc0ba5c496e5f33536df437ca5 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 18 Jan 2017 12:20:24 +0100 Subject: Doc: Clarify limitations of QNetworkProxy Task-number: QTBUG-58121 Change-Id: I3f7d960d5fabefe219a89cc5fa4752ead965ab0a Reviewed-by: Leena Miettinen --- src/webengine/doc/src/qtwebengine-overview.qdoc | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc index c3d737384..ff35b45cf 100644 --- a/src/webengine/doc/src/qtwebengine-overview.qdoc +++ b/src/webengine/doc/src/qtwebengine-overview.qdoc @@ -197,11 +197,16 @@ \section1 Proxy Support - Qt WebEngine uses the proxy settings from \l{Qt Network}. If - QNetworkProxy::applicationProxy is set, it will also be used for Qt WebEngine, and if - QNetworkProxyFactory::usesSystemConfiguration() is enabled, the proxy settings are automatically - retrieved from the system. Settings from an installed QNetworkProxyFactory will be ignored - though. + Qt WebEngine uses the proxy settings from \l{Qt Network}, and forwards them to Chromium's + networking stack. If QNetworkProxy::applicationProxy is set, it will also be used for Qt + WebEngine. If QNetworkProxyFactory::usesSystemConfiguration() is enabled, the proxy settings + are automatically retrieved from the system. Settings from an installed QNetworkProxyFactory + will be ignored, though. + + Not all properties of QNetworkProxy are supported by Qt WebEngine. That is, + QNetworkProxy::type(), QNetworkProxy::hostName() and QNetworkProxy::port() are taken into + account. All other proxy settings such as QNetworkProxy::rawHeader(), QNetworkProxy::user(), or + QNetworkProxy::password() are ignored. If a proxy requires authentication, QWebEnginePage::proxyAuthenticationRequired is emitted. For Qt Quick, a dialog is shown. -- cgit v1.2.3 From 4634c2467875e44a5cae5bc1ce015ca7a8115682 Mon Sep 17 00:00:00 2001 From: Peter Varga Date: Mon, 19 Dec 2016 16:16:53 +0100 Subject: Add back SIP (Software Input Panel) widget test Moreover, update the Chromium SHA1 for enabling virtual keyboard support for macOS. Task-number: QTBUG-55766 Change-Id: Ic50ae79ab13a62a4b9289afedce2d6647e266f86 Reviewed-by: Allan Sandfeld Jensen --- src/3rdparty | 2 +- .../auto/widgets/qwebenginepage/qwebenginepage.pro | 2 +- .../widgets/qwebenginepage/tst_qwebenginepage.cpp | 79 +-------------- .../auto/widgets/qwebengineview/qwebengineview.pro | 1 + .../widgets/qwebengineview/tst_qwebengineview.cpp | 112 +++++++++++++++++++++ 5 files changed, 116 insertions(+), 80 deletions(-) diff --git a/src/3rdparty b/src/3rdparty index 15d257fd9..965b67f25 160000 --- a/src/3rdparty +++ b/src/3rdparty @@ -1 +1 @@ -Subproject commit 15d257fd921f37b32ef643225f21df0ea24c8302 +Subproject commit 965b67f25e8af81ce1313287fe842f7a83e7d5ed diff --git a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro index df733c473..6446cdd7a 100644 --- a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro +++ b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro @@ -1,4 +1,4 @@ include(../tests.pri) -QT *= core-private gui-private +QT *= core-private contains(WEBENGINE_CONFIG, enable_pdf): DEFINES+=QWEBENGINEPAGE_PDFPRINTINGENABLED diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 821ab4757..059b20d4c 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -32,17 +32,15 @@ #include #include #include +#include #include -#include #include #include #include #include -#include #include #include #include -#include #include #include #include @@ -66,38 +64,6 @@ static void removeRecursive(const QString& dirname) QDir().rmdir(dirname); } -class TestInputContext : public QPlatformInputContext -{ -public: - TestInputContext() - : m_visible(false) - { - QInputMethodPrivate* inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod()); - inputMethodPrivate->testContext = this; - } - - ~TestInputContext() - { - QInputMethodPrivate* inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod()); - inputMethodPrivate->testContext = 0; - } - - virtual void showInputPanel() - { - m_visible = true; - } - virtual void hideInputPanel() - { - m_visible = false; - } - virtual bool isInputPanelVisible() const - { - return m_visible; - } - - bool m_visible; -}; - class tst_QWebEnginePage : public QObject { Q_OBJECT @@ -1741,32 +1707,6 @@ void tst_QWebEnginePage::inputMethods() clickOnPage(page, textInputCenter); - // This part of the test checks if the SIP (Software Input Panel) is triggered, - // which normally happens on mobile platforms, when a user input form receives - // a mouse click. - int inputPanel = 0; - if (viewType == "QWebEngineView") { - if (QWebEngineView* wv = qobject_cast(view)) - inputPanel = wv->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel); - } else if (viewType == "QGraphicsWebView") { - if (QGraphicsWebView* wv = qobject_cast(view)) - inputPanel = wv->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel); - } - - // For non-mobile platforms RequestSoftwareInputPanel event is not called - // because there is no SIP (Software Input Panel) triggered. In the case of a - // mobile platform, an input panel, e.g. virtual keyboard, is usually invoked - // and the RequestSoftwareInputPanel event is called. For these two situations - // this part of the test can verified as the checks below. - if (inputPanel) - QVERIFY(testContext.isInputPanelVisible()); - else - QVERIFY(!testContext.isInputPanelVisible()); - testContext.hideInputPanel(); - - clickOnPage(page, textInputCenter); - QVERIFY(testContext.isInputPanelVisible()); - //ImMicroFocus QVariant variant = page->inputMethodQuery(Qt::ImMicroFocus); QVERIFY(inputs.at(0).geometry().contains(variant.toRect().topLeft())); @@ -1970,14 +1910,6 @@ void tst_QWebEnginePage::inputMethods() clickOnPage(page, textInputCenter); QVERIFY(!(inputMethodHints(view) & Qt::ImhHiddenText)); - page->setHtml("

nothing to input here"); - testContext.hideInputPanel(); - - QWebEngineElement para = page->mainFrame()->findFirstElement("p"); - clickOnPage(page, para.geometry().center()); - - QVERIFY(!testContext.isInputPanelVisible()); - //START - Test for sending empty QInputMethodEvent page->setHtml("" \ "" \ @@ -2300,15 +2232,6 @@ void tst_QWebEnginePage::inputMethods() anchorPosition = variant.toInt(); QCOMPARE(anchorPosition, 12); - // Check sending RequestSoftwareInputPanel event - page->setHtml("" \ - "" \ - "

abc
"\ - ""); - QWebEngineElement inputElement = page->mainFrame()->findFirstElement("div"); - clickOnPage(page, inputElement.geometry().center()); - - QVERIFY(!testContext.isInputPanelVisible()); // START - Newline test for textarea qApp->processEvents(); diff --git a/tests/auto/widgets/qwebengineview/qwebengineview.pro b/tests/auto/widgets/qwebengineview/qwebengineview.pro index e99c7f493..d91c0074b 100644 --- a/tests/auto/widgets/qwebengineview/qwebengineview.pro +++ b/tests/auto/widgets/qwebengineview/qwebengineview.pro @@ -1 +1,2 @@ include(../tests.pri) +QT *= gui-private diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index 2baadd869..2acf2f939 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -22,8 +22,10 @@ #include #include "../util.h" +#include #include #include +#include #include #include #include @@ -36,6 +38,7 @@ #include #include #include +#include #define VERIFY_INPUTMETHOD_HINTS(actual, expect) \ QVERIFY(actual == expect); @@ -87,6 +90,8 @@ private Q_SLOTS: void inputMethodsTextFormat(); void keyboardEvents(); void keyboardFocusAfterPopup(); + + void softwareInputPanel(); }; // This will be called before the first test function is executed. @@ -1081,5 +1086,112 @@ void tst_QWebEngineView::keyboardFocusAfterPopup() QTRY_COMPARE(evaluateJavaScriptSync(webView->page(), "document.getElementById('input1').value").toString(), QStringLiteral("x")); } +class TestInputContext : public QPlatformInputContext +{ +public: + TestInputContext() + : m_visible(false) + { + QInputMethodPrivate* inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod()); + inputMethodPrivate->testContext = this; + } + + ~TestInputContext() + { + QInputMethodPrivate* inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod()); + inputMethodPrivate->testContext = 0; + } + + virtual void showInputPanel() + { + m_visible = true; + } + virtual void hideInputPanel() + { + m_visible = false; + } + virtual bool isInputPanelVisible() const + { + return m_visible; + } + + bool m_visible; +}; + +static QPoint elementCenter(QWebEnginePage *page, const QString &id) +{ + const QString jsCode( + "(function(){" + " var elem = document.getElementById('" + id + "');" + " var rect = elem.getBoundingClientRect();" + " return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2];" + "})()"); + QVariantList rectList = evaluateJavaScriptSync(page, jsCode).toList(); + + if (rectList.count() != 2) { + qWarning("elementCenter failed."); + return QPoint(); + } + + return QPoint(rectList.at(0).toInt(), rectList.at(1).toInt()); +} + +void tst_QWebEngineView::softwareInputPanel() +{ + TestInputContext testContext; + QWebEngineView view; + view.show(); + + QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool))); + view.setHtml("" + " " + ""); + QVERIFY(loadFinishedSpy.wait()); + + QPoint textInputCenter = elementCenter(view.page(), "input1"); + QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1")); + + // This part of the test checks if the SIP (Software Input Panel) is triggered, + // which normally happens on mobile platforms, when a user input form receives + // a mouse click. + int inputPanel = view.style()->styleHint(QStyle::SH_RequestSoftwareInputPanel); + + // For non-mobile platforms RequestSoftwareInputPanel event is not called + // because there is no SIP (Software Input Panel) triggered. In the case of a + // mobile platform, an input panel, e.g. virtual keyboard, is usually invoked + // and the RequestSoftwareInputPanel event is called. For these two situations + // this part of the test can verified as the checks below. + if (inputPanel) + QTRY_VERIFY(testContext.isInputPanelVisible()); + else + QTRY_VERIFY(!testContext.isInputPanelVisible()); + testContext.hideInputPanel(); + + QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter); + QTRY_VERIFY(testContext.isInputPanelVisible()); + + view.setHtml("

nothing to input here

"); + QVERIFY(loadFinishedSpy.wait()); + testContext.hideInputPanel(); + + QPoint paraCenter = elementCenter(view.page(), "para"); + QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, paraCenter); + + QVERIFY(!testContext.isInputPanelVisible()); + + // Check sending RequestSoftwareInputPanel event + view.page()->setHtml("" + " " + "
abc
" + ""); + QVERIFY(loadFinishedSpy.wait()); + + QPoint btnDivCenter = elementCenter(view.page(), "btnDiv"); + QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, btnDivCenter); + + QVERIFY(!testContext.isInputPanelVisible()); +} + QTEST_MAIN(tst_QWebEngineView) #include "tst_qwebengineview.moc" -- cgit v1.2.3 From 9cc6592de3029da98be34a54b56bbd004e93d569 Mon Sep 17 00:00:00 2001 From: Peter Varga Date: Mon, 19 Dec 2016 16:51:45 +0100 Subject: Make input method hints available via RWHV delegate widget Moreover, set ImHiddenText hint for password fields and add back the corresponding widget auto test. Task-number: QTBUG-55766 Change-Id: I3f76e19c8c33e11f3d9f515b6dc7d6e998c3c9a4 Reviewed-by: Allan Sandfeld Jensen --- src/core/render_widget_host_view_qt.cpp | 3 ++- src/core/render_widget_host_view_qt_delegate.h | 1 + .../render_widget_host_view_qt_delegate_quick.h | 1 + ...nder_widget_host_view_qt_delegate_quickwindow.h | 1 + .../render_widget_host_view_qt_delegate_widget.cpp | 5 ++++ .../render_widget_host_view_qt_delegate_widget.h | 1 + .../widgets/qwebenginepage/tst_qwebenginepage.cpp | 28 ---------------------- .../widgets/qwebengineview/tst_qwebengineview.cpp | 26 ++++++++++++++++++++ 8 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 70ffe0dcb..0a41d67ae 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -116,7 +116,7 @@ static inline Qt::InputMethodHints toQtInputMethodHints(ui::TextInputType inputT case ui::TEXT_INPUT_TYPE_SEARCH: return Qt::ImhPreferLowercase | Qt::ImhNoAutoUppercase; case ui::TEXT_INPUT_TYPE_PASSWORD: - return Qt::ImhSensitiveData | Qt::ImhNoPredictiveText | Qt::ImhNoAutoUppercase; + return Qt::ImhSensitiveData | Qt::ImhNoPredictiveText | Qt::ImhNoAutoUppercase | Qt::ImhHiddenText; case ui::TEXT_INPUT_TYPE_EMAIL: return Qt::ImhEmailCharactersOnly; case ui::TEXT_INPUT_TYPE_NUMBER: @@ -575,6 +575,7 @@ void RenderWidgetHostViewQt::TextInputStateChanged(const content::TextInputState { m_currentInputType = params.type; m_delegate->inputMethodStateChanged(params.type != ui::TEXT_INPUT_TYPE_NONE); + m_delegate->setInputMethodHints(toQtInputMethodHints(params.type)); } void RenderWidgetHostViewQt::ImeCancelComposition() diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h index 1e50c8f08..1e1234e72 100644 --- a/src/core/render_widget_host_view_qt_delegate.h +++ b/src/core/render_widget_host_view_qt_delegate.h @@ -112,6 +112,7 @@ public: virtual void resize(int width, int height) = 0; virtual void move(const QPoint &) = 0; virtual void inputMethodStateChanged(bool editorVisible) = 0; + virtual void setInputMethodHints(Qt::InputMethodHints hints) = 0; virtual void setClearColor(const QColor &color) = 0; }; diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.h b/src/webengine/render_widget_host_view_qt_delegate_quick.h index 385a98a3c..7a08e915b 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quick.h +++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h @@ -74,6 +74,7 @@ public: virtual void resize(int width, int height) Q_DECL_OVERRIDE; virtual void move(const QPoint&) Q_DECL_OVERRIDE { } virtual void inputMethodStateChanged(bool editorVisible) Q_DECL_OVERRIDE; + virtual void setInputMethodHints(Qt::InputMethodHints) Q_DECL_OVERRIDE { } // The QtQuick view doesn't have a backbuffer of its own and doesn't need this virtual void setClearColor(const QColor &) Q_DECL_OVERRIDE { } diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h index d0a5e480c..057b91c75 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h +++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h @@ -77,6 +77,7 @@ public: virtual void resize(int width, int height) Q_DECL_OVERRIDE; virtual void move(const QPoint &screenPos) Q_DECL_OVERRIDE; virtual void inputMethodStateChanged(bool) Q_DECL_OVERRIDE {} + virtual void setInputMethodHints(Qt::InputMethodHints) Q_DECL_OVERRIDE { } virtual void setClearColor(const QColor &) Q_DECL_OVERRIDE { } private: diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp index 27268d26b..69ecbe160 100644 --- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp +++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp @@ -323,6 +323,11 @@ void RenderWidgetHostViewQtDelegateWidget::inputMethodStateChanged(bool editorVi qApp->inputMethod()->setVisible(editorVisible); } +void RenderWidgetHostViewQtDelegateWidget::setInputMethodHints(Qt::InputMethodHints hints) +{ + QQuickWidget::setInputMethodHints(hints); +} + void RenderWidgetHostViewQtDelegateWidget::setClearColor(const QColor &color) { QQuickWidget::setClearColor(color); diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h index 68e6a176b..fb33c55c7 100644 --- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h +++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h @@ -75,6 +75,7 @@ public: virtual void resize(int width, int height) Q_DECL_OVERRIDE; virtual void move(const QPoint &screenPos) Q_DECL_OVERRIDE; virtual void inputMethodStateChanged(bool editorVisible) Q_DECL_OVERRIDE; + virtual void setInputMethodHints(Qt::InputMethodHints) Q_DECL_OVERRIDE; virtual void setClearColor(const QColor &color) Q_DECL_OVERRIDE; protected: diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 059b20d4c..00570a169 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -1637,24 +1637,6 @@ void tst_QWebEnginePage::inputMethods_data() } #if defined(QWEBENGINEPAGE_INPUTMETHODQUERY) -static Qt::InputMethodHints inputMethodHints(QObject* object) -{ - if (QGraphicsObject* o = qobject_cast(object)) - return o->inputMethodHints(); - if (QWidget* w = qobject_cast(object)) - return w->inputMethodHints(); - return Qt::InputMethodHints(); -} - -static bool inputMethodEnabled(QObject* object) -{ - if (QGraphicsObject* o = qobject_cast(object)) - return o->flags() & QGraphicsItem::ItemAcceptsInputMethod; - if (QWidget* w = qobject_cast(object)) - return w->testAttribute(Qt::WA_InputMethodEnabled); - return false; -} - static void clickOnPage(QWebEnginePage* page, const QPoint& position) { QMouseEvent evpres(QEvent::MouseButtonPress, position, Qt::LeftButton, Qt::NoButton, Qt::NoModifier); @@ -1900,16 +1882,6 @@ void tst_QWebEnginePage::inputMethods() //END - Tests for Selection when the Editor is not in Composition mode - //ImhHiddenText - QPoint passwordInputCenter = inputs.at(1).geometry().center(); - clickOnPage(page, passwordInputCenter); - - QVERIFY(inputMethodEnabled(view)); - QVERIFY(inputMethodHints(view) & Qt::ImhHiddenText); - - clickOnPage(page, textInputCenter); - QVERIFY(!(inputMethodHints(view) & Qt::ImhHiddenText)); - //START - Test for sending empty QInputMethodEvent page->setHtml("" \ "" \ diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index 2acf2f939..5b99f0787 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -92,6 +92,7 @@ private Q_SLOTS: void keyboardFocusAfterPopup(); void softwareInputPanel(); + void hiddenText(); }; // This will be called before the first test function is executed. @@ -1193,5 +1194,30 @@ void tst_QWebEngineView::softwareInputPanel() QVERIFY(!testContext.isInputPanelVisible()); } +void tst_QWebEngineView::hiddenText() +{ + QWebEngineView view; + view.show(); + + QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool))); + view.setHtml("" + "
" + " " + ""); + QVERIFY(loadFinishedSpy.wait()); + + QPoint passwordInputCenter = elementCenter(view.page(), "password1"); + QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, passwordInputCenter); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("password1")); + + QVERIFY(view.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled)); + QVERIFY(view.focusProxy()->inputMethodHints() & Qt::ImhHiddenText); + + QPoint textInputCenter = elementCenter(view.page(), "input1"); + QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1")); + QVERIFY(!(view.focusProxy()->inputMethodHints() & Qt::ImhHiddenText)); +} + QTEST_MAIN(tst_QWebEngineView) #include "tst_qwebengineview.moc" -- cgit v1.2.3 From 221f83d34a3dce9f185afe679290d600beb5b81b Mon Sep 17 00:00:00 2001 From: Ionut Alexandrescu Date: Fri, 20 Jan 2017 14:24:35 +0100 Subject: Fixing webengine spell checker example The languages submenu was not working corectly, languages could not be checked Change-Id: I7221d3527dbd6e071eb8d1585fb6d90812c61f94 Reviewed-by: Michal Klocek --- examples/webenginewidgets/spellchecker/webview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/webenginewidgets/spellchecker/webview.cpp b/examples/webenginewidgets/spellchecker/webview.cpp index 86e21ab13..0e52e7628 100644 --- a/examples/webenginewidgets/spellchecker/webview.cpp +++ b/examples/webenginewidgets/spellchecker/webview.cpp @@ -65,7 +65,7 @@ void WebView::contextMenuEvent(QContextMenuEvent *event) } QWebEngineProfile *profile = page()->profile(); - const QString &language = profile->spellCheckLanguages().first(); + const QStringList &languages = profile->spellCheckLanguages(); QMenu *menu = page()->createStandardContextMenu(); menu->addSeparator(); @@ -83,7 +83,7 @@ void WebView::contextMenuEvent(QContextMenuEvent *event) QAction *action = subMenu->addAction(str); action->setCheckable(true); QString lang = m_spellCheckLanguages[str]; - action->setChecked(language == lang); + action->setChecked(languages.contains(lang)); connect(action, &QAction::triggered, this, [profile, lang](){ profile->setSpellCheckLanguages(QStringList()< Date: Mon, 19 Dec 2016 17:36:50 +0100 Subject: Fix handling of empty input method events Task-number: QTBUG-55766 Change-Id: I4e6ade8f000f66ff1bb28f3b856ae140834292f1 Reviewed-by: Allan Sandfeld Jensen --- src/core/render_widget_host_view_qt.cpp | 5 +++- .../widgets/qwebenginepage/tst_qwebenginepage.cpp | 14 ----------- .../widgets/qwebengineview/tst_qwebengineview.cpp | 29 ++++++++++++++++++++++ 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 0a41d67ae..813bbe0d7 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -1114,7 +1114,10 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev) QGuiApplication::postEvent(qApp->focusObject(), eventCopy); } else { m_receivedEmptyImeText = false; - m_host->ImeCancelComposition(); + if (m_imeInProgress) { + m_imeInProgress = false; + m_host->ImeCancelComposition(); + } } } } diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 00570a169..13412ccba 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -1882,20 +1882,6 @@ void tst_QWebEnginePage::inputMethods() //END - Tests for Selection when the Editor is not in Composition mode - //START - Test for sending empty QInputMethodEvent - page->setHtml("" \ - "" \ - ""); - evaluateJavaScriptSync(page, "var inputEle = document.getElementById('input3'); inputEle.focus(); inputEle.select();"); - - //Send empty QInputMethodEvent - QInputMethodEvent emptyEvent; - page->event(&emptyEvent); - - QString inputValue = evaluateJavaScriptSync(page, "document.getElementById('input3').value").toString(); - QCOMPARE(inputValue, QString("QtWebEngine2")); - //END - Test for sending empty QInputMethodEvent - page->setHtml("" \ "" \ ""); diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index 5b99f0787..1160e4580 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -93,6 +93,7 @@ private Q_SLOTS: void softwareInputPanel(); void hiddenText(); + void emptyInputMethodEvent(); }; // This will be called before the first test function is executed. @@ -1219,5 +1220,33 @@ void tst_QWebEngineView::hiddenText() QVERIFY(!(view.focusProxy()->inputMethodHints() & Qt::ImhHiddenText)); } +void tst_QWebEngineView::emptyInputMethodEvent() +{ + QWebEngineView view; + view.show(); + + QSignalSpy selectionChangedSpy(&view, SIGNAL(selectionChanged())); + QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool))); + view.setHtml("" + " " + ""); + 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); + + // Send empty QInputMethodEvent + QInputMethodEvent emptyEvent; + QApplication::sendEvent(view.focusProxy(), &emptyEvent); + + QString inputValue = evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(); + QCOMPARE(inputValue, QString("QtWebEngine")); +} + QTEST_MAIN(tst_QWebEngineView) #include "tst_qwebengineview.moc" -- cgit v1.2.3