summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-01-25 11:45:23 +0100
committerLiang Qi <liang.qi@qt.io>2017-01-25 11:45:23 +0100
commitacf7f38b2b4a5d6427dca9b6538e3394cfde2d94 (patch)
treefcd5eeb1006b01a4596cce5956bfe32f3c055d29
parentc2447a308882ba3691d66b2c28df197f571518c7 (diff)
parent349ef9870917e8cf2c189fed4a970023b19ba24a (diff)
Merge remote-tracking branch 'origin/5.8' into dev
Conflicts: src/3rdparty tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp Change-Id: I070173576fc4be53689ce0dd9e1fd4133f5814da
-rw-r--r--examples/webenginewidgets/spellchecker/webview.cpp4
-rw-r--r--src/core/qtwebengine.gypi5
-rw-r--r--src/core/render_widget_host_view_qt.cpp8
-rw-r--r--src/core/render_widget_host_view_qt_delegate.h1
-rw-r--r--src/core/web_contents_adapter.cpp21
-rw-r--r--src/core/web_contents_adapter.h2
-rw-r--r--src/core/web_contents_adapter_p.h3
-rw-r--r--src/core/web_contents_view_qt.cpp13
-rw-r--r--src/webengine/doc/src/qtwebengine-overview.qdoc15
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.h1
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.h1
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp5
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h1
-rw-r--r--tests/auto/widgets/qwebenginepage/qwebenginepage.pro2
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp121
-rw-r--r--tests/auto/widgets/qwebengineview/qwebengineview.pro1
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp167
17 files changed, 222 insertions, 149 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()<<lang);
});
diff --git a/src/core/qtwebengine.gypi b/src/core/qtwebengine.gypi
index 5131ce8cc..b83b1cbfa 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',
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index fef3831e3..0d153dec2 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()
@@ -1115,7 +1116,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/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/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 9de2085ba..3763770d9 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -348,7 +348,7 @@ WebContentsAdapterPrivate::WebContentsAdapterPrivate()
, adapterClient(0)
, nextRequestId(CallbackDirectory::ReservedCallbackIdsEnd)
, lastFindRequestId(0)
- , currentDropAction(Qt::IgnoreAction)
+ , currentDropAction(blink::WebDragOperationNone)
, inDragUpdateLoop(false)
, updateDragCursorMessagePollingTimer(new QTimer)
{
@@ -1169,7 +1169,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](){
@@ -1246,6 +1246,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);
@@ -1273,13 +1284,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<blink::WebDragOperation>(action);
finishDragUpdate();
}
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index cb7f9b461..0accd3be5 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -168,7 +168,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 <base/callback.h>
#include "base/memory/ref_counted.h"
+#include <third_party/WebKit/public/platform/WebDragOperation.h>
#include <QScopedPointer>
#include <QSharedPointer>
@@ -93,7 +94,7 @@ public:
quint64 nextRequestId;
int lastFindRequestId;
std::unique_ptr<content::DropData> currentDropData;
- Qt::DropAction currentDropAction;
+ blink::WebDragOperation currentDropAction;
bool inDragUpdateLoop;
base::Closure dragUpdateLoopQuitClosure;
QScopedPointer<QTimer> 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)
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.
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/qwebenginepage.pro b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
index fef92c311..e0765736e 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, use_pdf): DEFINES+=QWEBENGINEPAGE_PDFPRINTINGENABLED
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 5467ce39e..71c949fff 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -32,17 +32,15 @@
#include <QOpenGLWidget>
#include <QPaintEngine>
#include <QPushButton>
+#include <QScreen>
#include <QStateMachine>
-#include <QStyle>
#include <QtGui/QClipboard>
#include <QtTest/QtTest>
#include <QTextCharFormat>
#include <QWebChannel>
-#include <private/qinputmethod_p.h>
#include <qnetworkcookiejar.h>
#include <qnetworkreply.h>
#include <qnetworkrequest.h>
-#include <qpa/qplatforminputcontext.h>
#include <qwebenginedownloaditem.h>
#include <qwebenginefullscreenrequest.h>
#include <qwebenginehistory.h>
@@ -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
@@ -1671,24 +1637,6 @@ void tst_QWebEnginePage::inputMethods_data()
}
#if defined(QWEBENGINEPAGE_INPUTMETHODQUERY)
-static Qt::InputMethodHints inputMethodHints(QObject* object)
-{
- if (QGraphicsObject* o = qobject_cast<QGraphicsObject*>(object))
- return o->inputMethodHints();
- if (QWidget* w = qobject_cast<QWidget*>(object))
- return w->inputMethodHints();
- return Qt::InputMethodHints();
-}
-
-static bool inputMethodEnabled(QObject* object)
-{
- if (QGraphicsObject* o = qobject_cast<QGraphicsObject*>(object))
- return o->flags() & QGraphicsItem::ItemAcceptsInputMethod;
- if (QWidget* w = qobject_cast<QWidget*>(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);
@@ -1741,32 +1689,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<QWebEngineView*>(view))
- inputPanel = wv->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel);
- } else if (viewType == "QGraphicsWebView") {
- if (QGraphicsWebView* wv = qobject_cast<QGraphicsWebView*>(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()));
@@ -1960,38 +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));
-
- page->setHtml("<html><body><p>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("<html><body>" \
- "<input type='text' id='input3' value='QtWebEngine2'/>" \
- "</body></html>");
- 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("<html><body>" \
"<input type='text' id='input4' value='QtWebEngine inputMethod'/>" \
"</body></html>");
@@ -2300,15 +2190,6 @@ void tst_QWebEnginePage::inputMethods()
anchorPosition = variant.toInt();
QCOMPARE(anchorPosition, 12);
- // Check sending RequestSoftwareInputPanel event
- page->setHtml("<html><body>" \
- "<input type='text' id='input5' value='QtWebEngine inputMethod'/>" \
- "<div id='btnDiv' onclick='i=document.getElementById(&quot;input5&quot;); i.focus();'>abc</div>"\
- "</body></html>");
- 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 53c7650fb..a9286c92d 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -22,8 +22,10 @@
#include <qtest.h>
#include "../util.h"
+#include <private/qinputmethod_p.h>
#include <qpainter.h>
#include <qpagelayout.h>
+#include <qpa/qplatforminputcontext.h>
#include <qwebengineview.h>
#include <qwebenginepage.h>
#include <qwebenginesettings.h>
@@ -39,6 +41,7 @@
#include <QtWebEngineCore/qwebenginehttprequest.h>
#include <QTcpServer>
#include <QTcpSocket>
+#include <QStyle>
#define VERIFY_INPUTMETHOD_HINTS(actual, expect) \
QVERIFY(actual == expect);
@@ -91,6 +94,10 @@ private Q_SLOTS:
void keyboardEvents();
void keyboardFocusAfterPopup();
void postData();
+
+ void softwareInputPanel();
+ void hiddenText();
+ void emptyInputMethodEvent();
};
// This will be called before the first test function is executed.
@@ -1216,5 +1223,165 @@ void tst_QWebEngineView::postData()
server.close();
}
+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("<html><body>"
+ " <input type='text' id='input1' value='' size='50'/>"
+ "</body></html>");
+ 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("<html><body><p id='para'>nothing to input here</p></body></html>");
+ 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("<html><body>"
+ " <input type='text' id='input1' value='QtWebEngine inputMethod'/>"
+ " <div id='btnDiv' onclick='i=document.getElementById(&quot;input1&quot;); i.focus();'>abc</div>"
+ "</body></html>");
+ QVERIFY(loadFinishedSpy.wait());
+
+ QPoint btnDivCenter = elementCenter(view.page(), "btnDiv");
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, btnDivCenter);
+
+ QVERIFY(!testContext.isInputPanelVisible());
+}
+
+void tst_QWebEngineView::hiddenText()
+{
+ QWebEngineView view;
+ view.show();
+
+ QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+ view.setHtml("<html><body>"
+ " <input type='text' id='input1' value='QtWebEngine' size='50'/><br>"
+ " <input type='password' id='password1'/>"
+ "</body></html>");
+ 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));
+}
+
+void tst_QWebEngineView::emptyInputMethodEvent()
+{
+ 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'/>"
+ "</body></html>");
+ 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"