Fix TextInput and TextEdit openInputPanel autotests
authorJoona Petrell <joona.t.petrell@nokia.com>
Wed, 28 Sep 2011 13:56:36 +0000 (16:56 +0300)
committerQt by Nokia <qt-info@nokia.com>
Thu, 29 Sep 2011 06:31:26 +0000 (08:31 +0200)
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 <qt_sanity_bot@ovi.com>
Reviewed-by: Andrew den Exter <andrew.den-exter@nokia.com>
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>

src/declarative/items/qsgcanvas.cpp
src/declarative/items/qsgtextedit.cpp
src/declarative/items/qsgtextedit_p_p.h
src/declarative/items/qsgtextinput.cpp
src/declarative/items/qsgtextinput_p_p.h
tests/auto/declarative/qsgtextedit/data/openInputPanel.qml
tests/auto/declarative/qsgtextedit/tst_qsgtextedit.cpp
tests/auto/declarative/qsgtextinput/data/openInputPanel.qml
tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp

index 8e5d1ec..cdef37f 100644 (file)
@@ -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
index 5c33a62..5cb061b 100644 (file)
@@ -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);
 }
 
index 326e0a3..7561977 100644 (file)
@@ -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;
index cfb1c6f..71c414f 100644 (file)
@@ -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);
 }
 
index 7022dd7..ed2395b 100644 (file)
@@ -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;
index 8998e55..d3aecf2 100644 (file)
@@ -1,6 +1,7 @@
 import QtQuick 2.0
 
 TextEdit {
+    width: 100; height: 100
     text: "Hello world"
     focus: false
 }
index 4b4ae74..3e92c35 100644 (file)
@@ -58,6 +58,7 @@
 #include <QDir>
 #include <QStyle>
 #include <QInputContext>
+#include <QInputPanel>
 #include <QClipboard>
 #include <QMimeData>
 #include <private/qtextcontrol_p.h>
@@ -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<QSGTextEdit *>(view.rootObject());
-    QVERIFY(edit);
-    QSignalSpy focusOnPressSpy(edit, SIGNAL(activeFocusOnPressChanged(bool)));
-
-    QSGItemPrivate* pri = QSGItemPrivate::get(edit);
-    QSGTextEditPrivate *editPrivate = static_cast<QSGTextEditPrivate*>(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<QSGTextEdit *>(view.rootObject());
     QVERIFY(edit);
-    QSignalSpy focusOnPressSpy(edit, SIGNAL(activeFocusOnPressChanged(bool)));
-
-    QSGItemPrivate* pri = QSGItemPrivate::get(edit);
-    QSGTextEditPrivate *editPrivate = static_cast<QSGTextEditPrivate*>(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<QObject*>(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<QObject*>(&anotherEdit));
+    QCOMPARE(inputPanelVisibilitySpy.count(), 0);
+
+    anotherEdit.setFocus(false);
+    QCOMPARE(qApp->inputPanel()->inputItem(), static_cast<QObject*>(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<QObject*>(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<QInputMethodEvent::Attribute>()));
-    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());
index 3924b2a..ca5cb26 100644 (file)
@@ -1,6 +1,7 @@
 import QtQuick 2.0
 
 TextInput {
+    width: 100; height: 100
     text: "Hello world"
     focus: false
 }
index 394c68d..5f9771a 100644 (file)
@@ -45,6 +45,7 @@
 #include <QFile>
 #include <QtDeclarative/qsgview.h>
 #include <QtGui/qguiapplication.h>
+#include <QInputPanel>
 #include <private/qsgtextinput_p.h>
 #include <private/qsgtextinput_p_p.h>
 #include <QDebug>
@@ -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<QSGTextInput *>(view.rootObject());
-    QVERIFY(input);
-
-    QSGItemPrivate* pri = QSGItemPrivate::get(input);
-    QSGTextInputPrivate *inputPrivate = static_cast<QSGTextInputPrivate*>(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<QSGTextInput *>(view.rootObject());
     QVERIFY(input);
-    QSignalSpy focusOnPressSpy(input, SIGNAL(activeFocusOnPressChanged(bool)));
 
-    QSGItemPrivate* pri = QSGItemPrivate::get(input);
-    QSGTextInputPrivate *inputPrivate = static_cast<QSGTextInputPrivate*>(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<QObject*>(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<QObject*>(&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<QObject*>(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<QObject*>(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<QInputMethodEvent::Attribute>()));
-    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());