From 65f07f3b95408b0a85590571118dd59a4171a9a2 Mon Sep 17 00:00:00 2001 From: Joona Petrell Date: Wed, 28 Sep 2011 16:56:36 +0300 Subject: [PATCH] Fix TextInput and TextEdit openInputPanel autotests Task-number: QTBUG-21691 The change also removes showInputPanelOnClick code from the TextInput and TextEdit, which was done to support Symbian^1 and ^3 fullscreen keyboards. Now by default the keyboard always follows editor focus. Change-Id: Id60a17fe51b3aa49ba9ea81b985e608e91c26145 Reviewed-on: http://codereview.qt-project.org/5733 Reviewed-by: Qt Sanity Bot Reviewed-by: Andrew den Exter Reviewed-by: Lars Knoll --- src/declarative/items/qsgcanvas.cpp | 5 +- src/declarative/items/qsgtextedit.cpp | 30 +-- src/declarative/items/qsgtextedit_p_p.h | 10 +- src/declarative/items/qsgtextinput.cpp | 30 +-- src/declarative/items/qsgtextinput_p_p.h | 9 - .../qsgtextedit/data/openInputPanel.qml | 1 + .../declarative/qsgtextedit/tst_qsgtextedit.cpp | 250 +++++--------------- .../qsgtextinput/data/openInputPanel.qml | 1 + .../declarative/qsgtextinput/tst_qsgtextinput.cpp | 249 ++++++-------------- 9 files changed, 145 insertions(+), 440 deletions(-) diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp index 8e5d1ec..cdef37f 100644 --- a/src/declarative/items/qsgcanvas.cpp +++ b/src/declarative/items/qsgcanvas.cpp @@ -722,7 +722,10 @@ void QSGCanvasPrivate::notifyFocusChangesRecur(QSGItem **items, int remaining) void QSGCanvasPrivate::updateInputMethodData() { - qApp->inputPanel()->setInputItem(activeFocusItem); + QSGItem *inputItem = 0; + if (activeFocusItem && activeFocusItem->flags() & QSGItem::ItemAcceptsInputMethod) + inputItem = activeFocusItem; + qApp->inputPanel()->setInputItem(inputItem); } QVariant QSGCanvas::inputMethodQuery(Qt::InputMethodQuery query) const diff --git a/src/declarative/items/qsgtextedit.cpp b/src/declarative/items/qsgtextedit.cpp index 5c33a62..5cb061b 100644 --- a/src/declarative/items/qsgtextedit.cpp +++ b/src/declarative/items/qsgtextedit.cpp @@ -1332,16 +1332,9 @@ void QSGTextEdit::mousePressEvent(QMouseEvent *event) if (d->focusOnPress){ bool hadActiveFocus = hasActiveFocus(); forceActiveFocus(); - if (d->showInputPanelOnFocus) { - if (hasActiveFocus() && hadActiveFocus && !isReadOnly()) { - // re-open input panel on press if already focused - openSoftwareInputPanel(); - } - } else { // show input panel on click - if (hasActiveFocus() && !hadActiveFocus) { - d->clickCausedFocus = true; - } - } + // re-open input panel on press if already focused + if (hasActiveFocus() && hadActiveFocus && !isReadOnly()) + openSoftwareInputPanel(); } d->control->processEvent(event, QPointF(0, -d->yoff)); if (!event->isAccepted()) @@ -1356,16 +1349,6 @@ void QSGTextEdit::mouseReleaseEvent(QMouseEvent *event) { Q_D(QSGTextEdit); d->control->processEvent(event, QPointF(0, -d->yoff)); - if (!d->showInputPanelOnFocus) { // input panel on click - if (d->focusOnPress && !isReadOnly() && boundingRect().contains(event->localPos())) { - // ### refactor: port properly - qDebug("QSGTextEdit: virtual keyboard handling not implemented"); -// if (canvas() && canvas() == qApp->focusWidget()) { -// qt_widget_private(canvas())->handleSoftwareInputPanel(event->button(), d->clickCausedFocus); -// } - } - } - d->clickCausedFocus = false; if (!event->isAccepted()) QSGImplicitSizeItem::mouseReleaseEvent(event); @@ -1972,11 +1955,8 @@ void QSGTextEdit::closeSoftwareInputPanel() void QSGTextEdit::focusInEvent(QFocusEvent *event) { Q_D(const QSGTextEdit); - if (d->showInputPanelOnFocus) { - if (d->focusOnPress && !isReadOnly()) { - openSoftwareInputPanel(); - } - } + if (d->focusOnPress && !isReadOnly()) + openSoftwareInputPanel(); QSGImplicitSizeItem::focusInEvent(event); } diff --git a/src/declarative/items/qsgtextedit_p_p.h b/src/declarative/items/qsgtextedit_p_p.h index 326e0a3..7561977 100644 --- a/src/declarative/items/qsgtextedit_p_p.h +++ b/src/declarative/items/qsgtextedit_p_p.h @@ -72,19 +72,13 @@ public: QSGTextEditPrivate() : color("black"), hAlign(QSGTextEdit::AlignLeft), vAlign(QSGTextEdit::AlignTop), documentDirty(true), dirty(false), richText(false), cursorVisible(false), focusOnPress(true), - showInputPanelOnFocus(true), clickCausedFocus(false), persistentSelection(true), - requireImplicitWidth(false), selectByMouse(false), canPaste(false), + persistentSelection(true), requireImplicitWidth(false), selectByMouse(false), canPaste(false), hAlignImplicit(true), rightToLeftText(false), isComplexRichText(false), textMargin(0.0), lastSelectionStart(0), lastSelectionEnd(0), cursorComponent(0), cursor(0), format(QSGTextEdit::AutoText), document(0), wrapMode(QSGTextEdit::NoWrap), mouseSelectionMode(QSGTextEdit::SelectCharacters), lineCount(0), yoff(0), nodeType(NodeIsNull), texture(0) { -#ifdef Q_OS_SYMBIAN - if (QSysInfo::symbianVersion() == QSysInfo::SV_SF_1 || QSysInfo::symbianVersion() == QSysInfo::SV_SF_3) { - showInputPanelOnFocus = false; - } -#endif } void init(); @@ -113,8 +107,6 @@ public: bool richText : 1; bool cursorVisible : 1; bool focusOnPress : 1; - bool showInputPanelOnFocus : 1; - bool clickCausedFocus : 1; bool persistentSelection : 1; bool requireImplicitWidth:1; bool selectByMouse:1; diff --git a/src/declarative/items/qsgtextinput.cpp b/src/declarative/items/qsgtextinput.cpp index cfb1c6f..71c414f 100644 --- a/src/declarative/items/qsgtextinput.cpp +++ b/src/declarative/items/qsgtextinput.cpp @@ -1105,16 +1105,9 @@ void QSGTextInput::mousePressEvent(QMouseEvent *event) if(d->focusOnPress){ bool hadActiveFocus = hasActiveFocus(); forceActiveFocus(); - if (d->showInputPanelOnFocus) { - if (hasActiveFocus() && hadActiveFocus && !isReadOnly()) { - // re-open input panel on press if already focused - openSoftwareInputPanel(); - } - } else { // show input panel on click - if (hasActiveFocus() && !hadActiveFocus) { - d->clickCausedFocus = true; - } - } + // re-open input panel on press if already focused + if (hasActiveFocus() && hadActiveFocus && !isReadOnly()) + openSoftwareInputPanel(); } if (d->selectByMouse) { setKeepMouseGrab(false); @@ -1158,16 +1151,6 @@ void QSGTextInput::mouseReleaseEvent(QMouseEvent *event) d->selectPressed = false; setKeepMouseGrab(false); } - if (!d->showInputPanelOnFocus) { // input panel on click - if (d->focusOnPress && !isReadOnly() && boundingRect().contains(event->localPos())) { - if (canvas() && canvas() == QGuiApplication::activeWindow()) { - // ### refactor: implement virtual keyboard properly.. - qDebug("QSGTextInput: virtual keyboard no implemented..."); -// qt_widget_private(canvas())->handleSoftwareInputPanel(event->button(), d->clickCausedFocus); - } - } - } - d->clickCausedFocus = false; d->control->processEvent(event); if (!event->isAccepted()) QSGImplicitSizeItem::mouseReleaseEvent(event); @@ -1797,11 +1780,8 @@ void QSGTextInput::closeSoftwareInputPanel() void QSGTextInput::focusInEvent(QFocusEvent *event) { Q_D(const QSGTextInput); - if (d->showInputPanelOnFocus) { - if (d->focusOnPress && !isReadOnly()) { - openSoftwareInputPanel(); - } - } + if (d->focusOnPress && !isReadOnly()) + openSoftwareInputPanel(); QSGImplicitSizeItem::focusInEvent(event); } diff --git a/src/declarative/items/qsgtextinput_p_p.h b/src/declarative/items/qsgtextinput_p_p.h index 7022dd7..ed2395b 100644 --- a/src/declarative/items/qsgtextinput_p_p.h +++ b/src/declarative/items/qsgtextinput_p_p.h @@ -88,8 +88,6 @@ public: , oldValidity(false) , focused(false) , focusOnPress(true) - , showInputPanelOnFocus(true) - , clickCausedFocus(false) , cursorVisible(false) , autoScroll(true) , selectByMouse(false) @@ -98,11 +96,6 @@ public: , selectPressed(false) , textLayoutDirty(true) { -#ifdef Q_OS_SYMBIAN - if (QSysInfo::symbianVersion() == QSysInfo::SV_SF_1 || QSysInfo::symbianVersion() == QSysInfo::SV_SF_3) { - showInputPanelOnFocus = false; - } -#endif } ~QSGTextInputPrivate() @@ -158,8 +151,6 @@ public: bool oldValidity:1; bool focused:1; bool focusOnPress:1; - bool showInputPanelOnFocus:1; - bool clickCausedFocus:1; bool cursorVisible:1; bool autoScroll:1; bool selectByMouse:1; diff --git a/tests/auto/declarative/qsgtextedit/data/openInputPanel.qml b/tests/auto/declarative/qsgtextedit/data/openInputPanel.qml index 8998e55..d3aecf2 100644 --- a/tests/auto/declarative/qsgtextedit/data/openInputPanel.qml +++ b/tests/auto/declarative/qsgtextedit/data/openInputPanel.qml @@ -1,6 +1,7 @@ import QtQuick 2.0 TextEdit { + width: 100; height: 100 text: "Hello world" focus: false } diff --git a/tests/auto/declarative/qsgtextedit/tst_qsgtextedit.cpp b/tests/auto/declarative/qsgtextedit/tst_qsgtextedit.cpp index 4b4ae74..3e92c35 100644 --- a/tests/auto/declarative/qsgtextedit/tst_qsgtextedit.cpp +++ b/tests/auto/declarative/qsgtextedit/tst_qsgtextedit.cpp @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -150,8 +151,7 @@ private slots: void canPaste(); void canPasteEmpty(); void textInput(); - void openInputPanelOnClick(); - void openInputPanelOnFocus(); + void openInputPanel(); void geometrySignals(); void pastingRichText_QTBUG_14003(); void implicitSize_data(); @@ -1931,7 +1931,7 @@ void tst_qsgtextedit::simulateKey(QSGView *view, int key, Qt::KeyboardModifiers class MyInputContext : public QInputContext { public: - MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false), updateReceived(false), eventType(QEvent::None) {} + MyInputContext() : updateReceived(false), eventType(QEvent::None) {} ~MyInputContext() {} QString identifierName() { return QString(); } @@ -1941,16 +1941,6 @@ public: bool isComposing() const { return false; } - bool filterEvent( const QEvent *event ) - { - if (event->type() == QEvent::RequestSoftwareInputPanel) - openInputPanelReceived = true; - if (event->type() == QEvent::CloseSoftwareInputPanel) - closeInputPanelReceived = true; - return QInputContext::filterEvent(event); - - } - void update() { updateReceived = true; } void sendPreeditText(const QString &text, int cursor) @@ -1974,8 +1964,6 @@ public: eventModifiers = event->modifiers(); } - bool openInputPanelReceived; - bool closeInputPanelReceived; bool updateReceived; int cursor; QEvent::Type eventType; @@ -2012,80 +2000,10 @@ void tst_qsgtextedit::textInput() QCOMPARE(editPrivate->text, QString("Hello world!")); } -void tst_qsgtextedit::openInputPanelOnClick() +void tst_qsgtextedit::openInputPanel() { -#ifdef QTBUG_21691 - QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort); - QVERIFY(false); -#else - QSGView view(QUrl::fromLocalFile(SRCDIR "/data/openInputPanel.qml")); - MyInputContext ic; - // QSGCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has focus - // and QWidget won't allow an input context to be set when the flag is not set. - view.setAttribute(Qt::WA_InputMethodEnabled, true); - view.setInputContext(&ic); - view.setAttribute(Qt::WA_InputMethodEnabled, false); - view.show(); - - qApp->setAutoSipEnabled(true); - view.requestActivateWindow(); - QTest::qWaitForWindowShown(&view); - QEXPECT_FAIL("", QTBUG_21489_MESSAGE, Continue); - QTRY_COMPARE(view.windowState(), Qt::WindowActive); - - QSGTextEdit *edit = qobject_cast(view.rootObject()); - QVERIFY(edit); - QSignalSpy focusOnPressSpy(edit, SIGNAL(activeFocusOnPressChanged(bool))); - - QSGItemPrivate* pri = QSGItemPrivate::get(edit); - QSGTextEditPrivate *editPrivate = static_cast(pri); - - // input panel on click - editPrivate->showInputPanelOnFocus = false; - - // No longer relevant? -// QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel( -// view.style()->styleHint(QStyle::SH_RequestSoftwareInputPanel)); - QTest::mouseClick(&view, Qt::LeftButton, 0, edit->mapToScene(QPointF(0,0)).toPoint()); - QGuiApplication::processEvents(); -// if (behavior == QStyle::RSIP_OnMouseClickAndAlreadyFocused) { -// QCOMPARE(ic.openInputPanelReceived, false); -// QTest::mouseClick(&view, Qt::LeftButton, 0, edit->mapToScene(QPointF(0,0)).toPoint()); -// QGuiApplication::processEvents(); -// QCOMPARE(ic.openInputPanelReceived, true); -// } else if (behavior == QStyle::RSIP_OnMouseClick) { - QCOMPARE(ic.openInputPanelReceived, true); -// } - ic.openInputPanelReceived = false; - - // focus should not cause input panels to open or close - edit->setFocus(false); - edit->setFocus(true); - edit->setFocus(false); - edit->setFocus(true); - edit->setFocus(false); - QGuiApplication::processEvents(); - QCOMPARE(ic.openInputPanelReceived, false); - QCOMPARE(ic.closeInputPanelReceived, false); -#endif -} - -void tst_qsgtextedit::openInputPanelOnFocus() -{ -#ifdef QTBUG_21691 - QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort); - QVERIFY(false); -#else QSGView view(QUrl::fromLocalFile(SRCDIR "/data/openInputPanel.qml")); - MyInputContext ic; - // QSGCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has focus - // and QWidget won't allow an input context to be set when the flag is not set. - view.setAttribute(Qt::WA_InputMethodEnabled, true); - view.setInputContext(&ic); - view.setAttribute(Qt::WA_InputMethodEnabled, false); view.show(); - - qApp->setAutoSipEnabled(true); view.requestActivateWindow(); QTest::qWaitForWindowShown(&view); QEXPECT_FAIL("", QTBUG_21489_MESSAGE, Continue); @@ -2093,121 +2011,81 @@ void tst_qsgtextedit::openInputPanelOnFocus() QSGTextEdit *edit = qobject_cast(view.rootObject()); QVERIFY(edit); - QSignalSpy focusOnPressSpy(edit, SIGNAL(activeFocusOnPressChanged(bool))); - - QSGItemPrivate* pri = QSGItemPrivate::get(edit); - QSGTextEditPrivate *editPrivate = static_cast(pri); - editPrivate->showInputPanelOnFocus = true; - // test default values + // check default values QVERIFY(edit->focusOnPress()); - QCOMPARE(ic.openInputPanelReceived, false); - QCOMPARE(ic.closeInputPanelReceived, false); - - // focus on press, input panel on focus - QTest::mousePress(&view, Qt::LeftButton, 0, edit->mapToScene(QPointF(0,0)).toPoint()); + QVERIFY(!edit->hasActiveFocus()); + qDebug() << &edit << qApp->inputPanel()->inputItem(); + QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); + QCOMPARE(qApp->inputPanel()->visible(), false); + + // input panel should open on focus + QPoint centerPoint(view.width()/2, view.height()/2); + Qt::KeyboardModifiers noModifiers = 0; + QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); QGuiApplication::processEvents(); QVERIFY(edit->hasActiveFocus()); - QCOMPARE(ic.openInputPanelReceived, true); - ic.openInputPanelReceived = false; - - // no events on release - QTest::mouseRelease(&view, Qt::LeftButton, 0, edit->mapToScene(QPointF(0,0)).toPoint()); - QCOMPARE(ic.openInputPanelReceived, false); - ic.openInputPanelReceived = false; + QCOMPARE(qApp->inputPanel()->inputItem(), edit); + QCOMPARE(qApp->inputPanel()->visible(), true); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); - // if already focused, input panel can be opened on press + // input panel should be re-opened when pressing already focused TextEdit + qApp->inputPanel()->hide(); + QCOMPARE(qApp->inputPanel()->visible(), false); QVERIFY(edit->hasActiveFocus()); - QTest::mousePress(&view, Qt::LeftButton, 0, edit->mapToScene(QPointF(0,0)).toPoint()); + QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); QGuiApplication::processEvents(); - QCOMPARE(ic.openInputPanelReceived, true); - ic.openInputPanelReceived = false; + QCOMPARE(qApp->inputPanel()->visible(), true); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); - // input method should stay enabled if focus - // is lost to an item that also accepts inputs + // input panel should stay visible if focus is lost to another text editor + QSignalSpy inputPanelVisibilitySpy(qApp->inputPanel(), SIGNAL(visibleChanged())); QSGTextEdit anotherEdit; anotherEdit.setParentItem(view.rootObject()); anotherEdit.setFocus(true); - QGuiApplication::processEvents(); - QCOMPARE(ic.openInputPanelReceived, true); - ic.openInputPanelReceived = false; - QCOMPARE(view.inputContext(), (QInputContext*)&ic); - QVERIFY(view.testAttribute(Qt::WA_InputMethodEnabled)); + QCOMPARE(qApp->inputPanel()->visible(), true); + QCOMPARE(qApp->inputPanel()->inputItem(), qobject_cast(&anotherEdit)); + QCOMPARE(inputPanelVisibilitySpy.count(), 0); + + anotherEdit.setFocus(false); + QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); + QCOMPARE(view.activeFocusItem(), view.rootItem()); + anotherEdit.setFocus(true); - // input method should be disabled if focus - // is lost to an item that doesn't accept inputs + // input item should be null if focus is lost to an item that doesn't accept inputs QSGItem item; item.setParentItem(view.rootObject()); item.setFocus(true); + QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); + QCOMPARE(view.activeFocusItem(), &item); + + qApp->inputPanel()->hide(); + + // input panel should not be opened if TextEdit is read only + edit->setReadOnly(true); + edit->setFocus(true); + QCOMPARE(qApp->inputPanel()->visible(), false); + QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); QGuiApplication::processEvents(); - QCOMPARE(ic.openInputPanelReceived, false); - QVERIFY(view.inputContext() == 0); - QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled)); + QCOMPARE(qApp->inputPanel()->visible(), false); - // no automatic input panel events should - // be sent if activeFocusOnPress is false - edit->setFocusOnPress(false); - QCOMPARE(focusOnPressSpy.count(),1); + // input panel should not be opened if focusOnPress is set to false edit->setFocusOnPress(false); - QCOMPARE(focusOnPressSpy.count(),1); edit->setFocus(false); edit->setFocus(true); - QTest::mousePress(&view, Qt::LeftButton, 0, edit->mapToScene(QPointF(0,0)).toPoint()); - QTest::mouseRelease(&view, Qt::LeftButton, 0, edit->mapToScene(QPointF(0,0)).toPoint()); - QGuiApplication::processEvents(); - QCOMPARE(ic.openInputPanelReceived, false); - QCOMPARE(ic.closeInputPanelReceived, false); + QCOMPARE(qApp->inputPanel()->visible(), false); + QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); + QCOMPARE(qApp->inputPanel()->visible(), false); - // one show input panel event should - // be set when openSoftwareInputPanel is called + // input panel should open when openSoftwareInputPanel is called edit->openSoftwareInputPanel(); - QCOMPARE(ic.openInputPanelReceived, true); - QCOMPARE(ic.closeInputPanelReceived, false); - ic.openInputPanelReceived = false; + QCOMPARE(qApp->inputPanel()->visible(), true); - // one close input panel event should - // be sent when closeSoftwareInputPanel is called + // input panel should close when closeSoftwareInputPanel is called edit->closeSoftwareInputPanel(); - QCOMPARE(ic.openInputPanelReceived, false); - QCOMPARE(ic.closeInputPanelReceived, true); - ic.closeInputPanelReceived = false; - - // set activeFocusOnPress back to true - edit->setFocusOnPress(true); - QCOMPARE(focusOnPressSpy.count(),2); - edit->setFocusOnPress(true); - QCOMPARE(focusOnPressSpy.count(),2); - edit->setFocus(false); - QGuiApplication::processEvents(); - QCOMPARE(ic.openInputPanelReceived, false); - QCOMPARE(ic.closeInputPanelReceived, false); - ic.closeInputPanelReceived = false; - - // input panel should not re-open - // if focus has already been set - edit->setFocus(true); - QCOMPARE(ic.openInputPanelReceived, true); - ic.openInputPanelReceived = false; - edit->setFocus(true); - QCOMPARE(ic.openInputPanelReceived, false); - - // input method should be disabled - // if TextEdit loses focus - edit->setFocus(false); - QGuiApplication::processEvents(); - QVERIFY(view.inputContext() == 0); - QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled)); - - // input method should not be enabled - // if TextEdit is read only. - edit->setReadOnly(true); - ic.openInputPanelReceived = false; - edit->setFocus(true); - QGuiApplication::processEvents(); - QCOMPARE(ic.openInputPanelReceived, false); - QVERIFY(view.inputContext() == 0); - QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled)); -#endif + QCOMPARE(qApp->inputPanel()->visible(), false); } void tst_qsgtextedit::geometrySignals() @@ -2328,12 +2206,6 @@ void tst_qsgtextedit::preeditMicroFocus() QString preeditText = "super"; QSGView view(QUrl::fromLocalFile(SRCDIR "/data/inputMethodEvent.qml")); - MyInputContext ic; - // QSGCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has focus - // and QWidget won't allow an input context to be set when the flag is not set. - view.setAttribute(Qt::WA_InputMethodEnabled, true); - view.setInputContext(&ic); - view.setAttribute(Qt::WA_InputMethodEnabled, false); view.show(); view.requestActivateWindow(); QTest::qWaitForWindowShown(&view); @@ -2346,13 +2218,13 @@ void tst_qsgtextedit::preeditMicroFocus() QSignalSpy cursorRectangleSpy(edit, SIGNAL(cursorRectangleChanged())); QRect currentRect; - QRect previousRect = edit->inputMethodQuery(Qt::ImMicroFocus).toRect(); + QRect previousRect = edit->inputMethodQuery(Qt::ImCursorRectangle).toRect(); // Verify that the micro focus rect is positioned the same for position 0 as // it would be if there was no preedit text. ic.updateReceived = false; ic.sendPreeditText(preeditText, 0); - currentRect = edit->inputMethodQuery(Qt::ImMicroFocus).toRect(); + currentRect = edit->inputMethodQuery(Qt::ImCursorRectangle).toRect(); QCOMPARE(currentRect, previousRect); #if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) QCOMPARE(ic.updateReceived, false); // The cursor position hasn't changed. @@ -2364,7 +2236,7 @@ void tst_qsgtextedit::preeditMicroFocus() for (int i = 1; i <= 5; ++i) { ic.updateReceived = false; ic.sendPreeditText(preeditText, i); - currentRect = edit->inputMethodQuery(Qt::ImMicroFocus).toRect(); + currentRect = edit->inputMethodQuery(Qt::ImCursorRectangle).toRect(); QVERIFY(previousRect.left() < currentRect.left()); #if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) QCOMPARE(ic.updateReceived, true); @@ -2379,7 +2251,7 @@ void tst_qsgtextedit::preeditMicroFocus() ic.sendPreeditText(preeditText, 0); ic.updateReceived = false; ic.sendEvent(QInputMethodEvent(preeditText, QList())); - currentRect = edit->inputMethodQuery(Qt::ImMicroFocus).toRect(); + currentRect = edit->inputMethodQuery(Qt::ImCursorRectangle).toRect(); QCOMPARE(currentRect, previousRect); #if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) QCOMPARE(ic.updateReceived, true); @@ -2568,8 +2440,8 @@ void tst_qsgtextedit::cursorRectangleSize() QVERIFY(textEdit != 0); textEdit->setFocus(Qt::OtherFocusReason); QRectF cursorRect = textEdit->positionToRectangle(textEdit->cursorPosition()); - QRectF microFocusFromScene = canvas->inputMethodQuery(Qt::ImMicroFocus).toRectF(); - QRectF microFocusFromApp= QGuiApplication::focusWidget()->inputMethodQuery(Qt::ImMicroFocus).toRectF(); + QRectF microFocusFromScene = canvas->inputMethodQuery(Qt::ImCursorRectangle).toRectF(); + QRectF microFocusFromApp= QGuiApplication::focusWidget()->inputMethodQuery(Qt::ImCursorRectangle).toRectF(); QCOMPARE(microFocusFromScene.size(), cursorRect.size()); QCOMPARE(microFocusFromApp.size(), cursorRect.size()); diff --git a/tests/auto/declarative/qsgtextinput/data/openInputPanel.qml b/tests/auto/declarative/qsgtextinput/data/openInputPanel.qml index 3924b2a..ca5cb26 100644 --- a/tests/auto/declarative/qsgtextinput/data/openInputPanel.qml +++ b/tests/auto/declarative/qsgtextinput/data/openInputPanel.qml @@ -1,6 +1,7 @@ import QtQuick 2.0 TextInput { + width: 100; height: 100 text: "Hello world" focus: false } diff --git a/tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp b/tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp index 394c68d..5f9771a 100644 --- a/tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp +++ b/tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -134,8 +135,7 @@ private slots: void canPaste(); void readOnly(); - void openInputPanelOnClick(); - void openInputPanelOnFocus(); + void openInputPanel(); void setHAlignClearCache(); void focusOutClearSelection(); @@ -1842,7 +1842,7 @@ void tst_qsgtextinput::cursorRectangle() QVERIFY(r.left() < textWidth + error); QVERIFY(r.right() > textWidth - error); - QCOMPARE(input.inputMethodQuery(Qt::ImMicroFocus).toRect(), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); } // Check the cursor rectangle remains within the input bounding rect when auto scrolling. @@ -1852,14 +1852,14 @@ void tst_qsgtextinput::cursorRectangle() for (int i = 6; i < text.length(); ++i) { input.setCursorPosition(i); QCOMPARE(r, input.cursorRectangle()); - QCOMPARE(input.inputMethodQuery(Qt::ImMicroFocus).toRect(), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); } for (int i = text.length() - 2; i >= 0; --i) { input.setCursorPosition(i); r = input.cursorRectangle(); QVERIFY(r.right() >= 0); - QCOMPARE(input.inputMethodQuery(Qt::ImMicroFocus).toRect(), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); } input.setText("Hi!"); @@ -2033,7 +2033,7 @@ void tst_qsgtextinput::simulateKey(QSGView *view, int key) class MyInputContext : public QInputContext { public: - MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false), updateReceived(false), eventType(QEvent::None) {} + MyInputContext() : updateReceived(false), eventType(QEvent::None) {} ~MyInputContext() {} QString identifierName() { return QString(); } @@ -2043,15 +2043,6 @@ public: bool isComposing() const { return false; } - bool filterEvent( const QEvent *event ) - { - if (event->type() == QEvent::RequestSoftwareInputPanel) - openInputPanelReceived = true; - if (event->type() == QEvent::CloseSoftwareInputPanel) - closeInputPanelReceived = true; - return QInputContext::filterEvent(event); - } - void update() { updateReceived = true; } void mouseHandler(int x, QMouseEvent *event) @@ -2075,8 +2066,6 @@ public: sendEvent(event); } - bool openInputPanelReceived; - bool closeInputPanelReceived; bool updateReceived; int cursor; QEvent::Type eventType; @@ -2088,196 +2077,92 @@ public: }; #endif -void tst_qsgtextinput::openInputPanelOnClick() +void tst_qsgtextinput::openInputPanel() { -#ifdef QTBUG_21691 - QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort); - QVERIFY(false); -#else QSGView view(QUrl::fromLocalFile(SRCDIR "/data/openInputPanel.qml")); - MyInputContext ic; - // QSGCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has focus - // and QWidget won't allow an input context to be set when the flag is not set. - view.setAttribute(Qt::WA_InputMethodEnabled, true); - view.setInputContext(&ic); - view.setAttribute(Qt::WA_InputMethodEnabled, false); view.show(); - QGuiApplication::setActiveWindow(&view); + view.requestActivateWindow(); QTest::qWaitForWindowShown(&view); QEXPECT_FAIL("", QTBUG_21489_MESSAGE, Continue); QTRY_COMPARE(view.windowState(), Qt::WindowActive); - QSGTextInput *input = qobject_cast(view.rootObject()); - QVERIFY(input); - - QSGItemPrivate* pri = QSGItemPrivate::get(input); - QSGTextInputPrivate *inputPrivate = static_cast(pri); - - // input panel on click - inputPrivate->showInputPanelOnFocus = false; - // No longer relevant? -// QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel( -// view.style()->styleHint(QStyle::SH_RequestSoftwareInputPanel)); - QTest::mouseClick(&view, Qt::LeftButton, 0, input->pos().toPoint()); - QApplication::processEvents(); -// if (behavior == QStyle::RSIP_OnMouseClickAndAlreadyFocused) { -// QCOMPARE(ic.openInputPanelReceived, false); -// QTest::mouseClick(&view, Qt::LeftButton, 0, input->pos().toPoint()); -// QApplication::processEvents(); -// QCOMPARE(ic.openInputPanelReceived, true); -// } else if (behavior == QStyle::RSIP_OnMouseClick) { - QCOMPARE(ic.openInputPanelReceived, true); -// } - ic.openInputPanelReceived = false; - - - - // focus should not cause input panels to open or close - input->setFocus(false); - input->setFocus(true); - input->setFocus(false); - input->setFocus(true); - input->setFocus(false); - QCOMPARE(ic.openInputPanelReceived, false); - QCOMPARE(ic.closeInputPanelReceived, false); -#endif -} - -void tst_qsgtextinput::openInputPanelOnFocus() -{ -#ifdef QTBUG_21691 - QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort); - QVERIFY(false); -#else - QSGView view(QUrl::fromLocalFile(SRCDIR "/data/openInputPanel.qml")); - MyInputContext ic; - // QSGCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has focus - // and QWidget won't allow an input context to be set when the flag is not set. - view.setAttribute(Qt::WA_InputMethodEnabled, true); - view.setInputContext(&ic); - view.setAttribute(Qt::WA_InputMethodEnabled, false); - view.show(); - QGuiApplication::setActiveWindow(&view); - QTest::qWaitForWindowShown(&view); - QEXPECT_FAIL("", QTBUG_21489_MESSAGE, Continue); - QTRY_COMPARE(view.windowState(), Qt::WindowActive); QSGTextInput *input = qobject_cast(view.rootObject()); QVERIFY(input); - QSignalSpy focusOnPressSpy(input, SIGNAL(activeFocusOnPressChanged(bool))); - QSGItemPrivate* pri = QSGItemPrivate::get(input); - QSGTextInputPrivate *inputPrivate = static_cast(pri); - inputPrivate->showInputPanelOnFocus = true; - - // test default values + // check default values QVERIFY(input->focusOnPress()); - QCOMPARE(ic.openInputPanelReceived, false); - QCOMPARE(ic.closeInputPanelReceived, false); - - // focus on press, input panel on focus - QTest::mousePress(&view, Qt::LeftButton, 0, input->pos().toPoint()); + QVERIFY(!input->hasActiveFocus()); + qDebug() << &input << qApp->inputPanel()->inputItem(); + QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); + QCOMPARE(qApp->inputPanel()->visible(), false); + + // input panel should open on focus + QPoint centerPoint(view.width()/2, view.height()/2); + Qt::KeyboardModifiers noModifiers = 0; + QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); QGuiApplication::processEvents(); QVERIFY(input->hasActiveFocus()); - QCOMPARE(ic.openInputPanelReceived, true); - ic.openInputPanelReceived = false; + QCOMPARE(qApp->inputPanel()->inputItem(), input); + QCOMPARE(qApp->inputPanel()->visible(), true); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); - // no events on release - QTest::mouseRelease(&view, Qt::LeftButton, 0, input->pos().toPoint()); - QCOMPARE(ic.openInputPanelReceived, false); - ic.openInputPanelReceived = false; - - // if already focused, input panel can be opened on press + // input panel should be re-opened when pressing already focused TextInput + qApp->inputPanel()->hide(); + QCOMPARE(qApp->inputPanel()->visible(), false); QVERIFY(input->hasActiveFocus()); - QTest::mousePress(&view, Qt::LeftButton, 0, input->pos().toPoint()); + QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); QGuiApplication::processEvents(); - QCOMPARE(ic.openInputPanelReceived, true); - ic.openInputPanelReceived = false; + QCOMPARE(qApp->inputPanel()->visible(), true); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); - // input method should stay enabled if focus - // is lost to an item that also accepts inputs + // input panel should stay visible if focus is lost to another text inputor + QSignalSpy inputPanelVisibilitySpy(qApp->inputPanel(), SIGNAL(visibleChanged())); QSGTextInput anotherInput; - anotherInput.setParentItem(view.rootItem()); + anotherInput.setParentItem(view.rootObject()); anotherInput.setFocus(true); - QGuiApplication::processEvents(); - QCOMPARE(ic.openInputPanelReceived, true); - ic.openInputPanelReceived = false; - QCOMPARE(view.inputContext(), (QInputContext*)&ic); - QVERIFY(view.testAttribute(Qt::WA_InputMethodEnabled)); + QCOMPARE(qApp->inputPanel()->visible(), true); + QCOMPARE(qApp->inputPanel()->inputItem(), qobject_cast(&anotherInput)); + QCOMPARE(inputPanelVisibilitySpy.count(), 0); - // input method should be disabled if focus - // is lost to an item that doesn't accept inputs + anotherInput.setFocus(false); + QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); + QCOMPARE(view.activeFocusItem(), view.rootItem()); + anotherInput.setFocus(true); + + // input item should be null if focus is lost to an item that doesn't accept inputs QSGItem item; - item.setParentItem(view.rootItem()); + item.setParentItem(view.rootObject()); item.setFocus(true); + QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); + QCOMPARE(view.activeFocusItem(), &item); + + qApp->inputPanel()->hide(); + + // input panel should not be opened if TextInput is read only + input->setReadOnly(true); + input->setFocus(true); + QCOMPARE(qApp->inputPanel()->visible(), false); + QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); QGuiApplication::processEvents(); - QCOMPARE(ic.openInputPanelReceived, false); - QVERIFY(view.inputContext() == 0); - QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled)); + QCOMPARE(qApp->inputPanel()->visible(), false); - // no automatic input panel events should - // be sent if activeFocusOnPress is false - input->setFocusOnPress(false); - QCOMPARE(focusOnPressSpy.count(),1); + // input panel should not be opened if focusOnPress is set to false input->setFocusOnPress(false); - QCOMPARE(focusOnPressSpy.count(),1); input->setFocus(false); input->setFocus(true); - QTest::mousePress(&view, Qt::LeftButton, 0, input->pos().toPoint()); - QTest::mouseRelease(&view, Qt::LeftButton, 0, input->pos().toPoint()); - QGuiApplication::processEvents(); - QCOMPARE(ic.openInputPanelReceived, false); - QCOMPARE(ic.closeInputPanelReceived, false); + QCOMPARE(qApp->inputPanel()->visible(), false); + QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); + QCOMPARE(qApp->inputPanel()->visible(), false); - // one show input panel event should - // be set when openSoftwareInputPanel is called + // input panel should open when openSoftwareInputPanel is called input->openSoftwareInputPanel(); - QCOMPARE(ic.openInputPanelReceived, true); - QCOMPARE(ic.closeInputPanelReceived, false); - ic.openInputPanelReceived = false; + QCOMPARE(qApp->inputPanel()->visible(), true); - // one close input panel event should - // be sent when closeSoftwareInputPanel is called + // input panel should close when closeSoftwareInputPanel is called input->closeSoftwareInputPanel(); - QCOMPARE(ic.openInputPanelReceived, false); - QCOMPARE(ic.closeInputPanelReceived, true); - ic.closeInputPanelReceived = false; - - // set activeFocusOnPress back to true - input->setFocusOnPress(true); - QCOMPARE(focusOnPressSpy.count(),2); - input->setFocusOnPress(true); - QCOMPARE(focusOnPressSpy.count(),2); - input->setFocus(false); - QGuiApplication::processEvents(); - QCOMPARE(ic.openInputPanelReceived, false); - QCOMPARE(ic.closeInputPanelReceived, false); - ic.closeInputPanelReceived = false; - - // input panel should not re-open - // if focus has already been set - input->setFocus(true); - QCOMPARE(ic.openInputPanelReceived, true); - ic.openInputPanelReceived = false; - input->setFocus(true); - QCOMPARE(ic.openInputPanelReceived, false); - - // input method should be disabled - // if TextInput loses focus - input->setFocus(false); - QGuiApplication::processEvents(); - QVERIFY(view.inputContext() == 0); - QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled)); - - // input method should not be enabled - // if TextEdit is read only. - input->setReadOnly(true); - ic.openInputPanelReceived = false; - input->setFocus(true); - QGuiApplication::processEvents(); - QCOMPARE(ic.openInputPanelReceived, false); - QVERIFY(view.inputContext() == 0); - QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled)); -#endif + QCOMPARE(qApp->inputPanel()->visible(), false); } class MyTextInput : public QSGTextInput @@ -2500,13 +2385,13 @@ void tst_qsgtextinput::preeditMicroFocus() QVERIFY(input); QRect currentRect; - QRect previousRect = input->inputMethodQuery(Qt::ImMicroFocus).toRect(); + QRect previousRect = input->inputMethodQuery(Qt::ImCursorRectangle).toRect(); // Verify that the micro focus rect is positioned the same for position 0 as // it would be if there was no preedit text. ic.updateReceived = false; ic.sendPreeditText(preeditText, 0); - currentRect = input->inputMethodQuery(Qt::ImMicroFocus).toRect(); + currentRect = input->inputMethodQuery(Qt::ImCursorRectangle).toRect(); QCOMPARE(currentRect, previousRect); #if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) QCOMPARE(ic.updateReceived, true); @@ -2517,7 +2402,7 @@ void tst_qsgtextinput::preeditMicroFocus() for (int i = 1; i <= 5; ++i) { ic.updateReceived = false; ic.sendPreeditText(preeditText, i); - currentRect = input->inputMethodQuery(Qt::ImMicroFocus).toRect(); + currentRect = input->inputMethodQuery(Qt::ImCursorRectangle).toRect(); QVERIFY(previousRect.left() < currentRect.left()); #if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) QCOMPARE(ic.updateReceived, true); @@ -2530,7 +2415,7 @@ void tst_qsgtextinput::preeditMicroFocus() ic.sendPreeditText(preeditText, 0); ic.updateReceived = false; ic.sendEvent(QInputMethodEvent(preeditText, QList())); - currentRect = input->inputMethodQuery(Qt::ImMicroFocus).toRect(); + currentRect = input->inputMethodQuery(Qt::ImCursorRectangle).toRect(); QCOMPARE(currentRect, previousRect); #if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) QCOMPARE(ic.updateReceived, true); @@ -2714,8 +2599,8 @@ void tst_qsgtextinput::cursorRectangleSize() QVERIFY(textInput != 0); textInput->setFocus(Qt::OtherFocusReason); QRectF cursorRect = textInput->positionToRectangle(textInput->cursorPosition()); - QRectF microFocusFromScene = canvas->inputMethodQuery(Qt::ImMicroFocus).toRectF(); - QRectF microFocusFromApp= QGuiApplication::focusWidget()->inputMethodQuery(Qt::ImMicroFocus).toRectF(); + QRectF microFocusFromScene = canvas->inputMethodQuery(Qt::ImCursorRectangle).toRectF(); + QRectF microFocusFromApp= QGuiApplication::focusWidget()->inputMethodQuery(Qt::ImCursorRectangle).toRectF(); QCOMPARE(microFocusFromScene.size(), cursorRect.size()); QCOMPARE(microFocusFromApp.size(), cursorRect.size()); -- 1.7.2.5