Fix cursor blinking for TextInput and TextEdit
authorSimon Hausmann <simon.hausmann@digia.com>
Mon, 25 Aug 2014 09:06:58 +0000 (11:06 +0200)
committerSimon Hausmann <simon.hausmann@digia.com>
Tue, 26 Aug 2014 10:59:23 +0000 (12:59 +0200)
Before commit fb339b21b8a24b835cea7a057c47b7c5ad80dd72 relied on the simple
transparent rectangle node to remain invisible. After that commit we used the
regular rectangle node, which doesn't seem to like toggling the color between
transparent and solid black and therefore the cursor was always visible.

As advised by Gunnar this patch implements a much simpler logic: When the
cursor is supposed to be invisible, we just don't create a scene graph node for
it anymore.

Change-Id: I7b0e173f6d37997559ee0911f37903efdb14847f
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
src/quick/items/qquicktextedit.cpp
src/quick/items/qquicktextinput.cpp
src/quick/items/qquicktextinput_p_p.h
src/quick/items/qquicktextnode.cpp
src/quick/items/qquicktextnode_p.h

index e8c2199..aca7150 100644 (file)
@@ -153,8 +153,10 @@ namespace {
                 removeChildNode(cursorNode);
             delete cursorNode;
             cursorNode = newNode;
-            appendChildNode(cursorNode);
-            cursorNode->setFlag(QSGNode::OwnedByParent);
+            if (cursorNode) {
+                appendChildNode(cursorNode);
+                cursorNode->setFlag(QSGNode::OwnedByParent);
+            }
         }
 
         QSGRectangleNode *cursorNode;
@@ -1903,10 +1905,10 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
     }
 
     if (d->cursorComponent == 0 && !isReadOnly()) {
-        QColor color = (!d->cursorVisible || !d->control->cursorOn())
-                ? QColor(0, 0, 0, 0)
-                : d->color;
-        rootNode->resetCursorNode(d->sceneGraphContext()->createRectangleNode(cursorRectangle(), color));
+        QSGRectangleNode* cursor = 0;
+        if (d->cursorVisible && d->control->cursorOn())
+            cursor = d->sceneGraphContext()->createRectangleNode(cursorRectangle(), d->color);
+        rootNode->resetCursorNode(cursor);
     }
 
     return rootNode;
index d3d4bde..c91b79d 100644 (file)
@@ -1852,17 +1852,13 @@ QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
         node = new QQuickTextNode(this);
     d->textNode = node;
 
-    if (!d->textLayoutDirty && oldNode != 0) {
-        QSGRectangleNode *cursorNode = node->cursorNode();
-        if (cursorNode != 0 && !isReadOnly()) {
-            cursorNode->setRect(cursorRectangle());
+    const bool showCursor = !isReadOnly() && d->cursorItem == 0 && d->cursorVisible && (d->m_blinkStatus || d->m_blinkPeriod == 0);
 
-            if (!d->cursorVisible || d->cursorItem || (!d->m_blinkStatus && d->m_blinkPeriod > 0)) {
-                d->hideCursor();
-            } else {
-                d->showCursor();
-            }
-        }
+    if (!d->textLayoutDirty && oldNode != 0) {
+        if (showCursor)
+            node->setCursor(cursorRectangle(), d->color);
+        else
+            node->clearCursor();
     } else {
         node->setUseNativeRenderer(d->renderType == NativeRendering);
         node->deleteContent();
@@ -1890,14 +1886,8 @@ QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
                                                                  // selection
         }
 
-        if (!isReadOnly() && d->cursorItem == 0) {
-            node->setCursor(cursorRectangle(), d->color);
-            if (!d->cursorVisible || (!d->m_blinkStatus && d->m_blinkPeriod > 0)) {
-                d->hideCursor();
-            } else {
-                d->showCursor();
-            }
-        }
+        if (showCursor)
+                node->setCursor(cursorRectangle(), d->color);
 
         d->textLayoutDirty = false;
     }
@@ -2696,24 +2686,6 @@ void QQuickTextInput::selectionChanged()
     }
 }
 
-void QQuickTextInputPrivate::showCursor()
-{
-    if (textNode != 0 && textNode->cursorNode() != 0) {
-        QSGRectangleNode *cursor = textNode->cursorNode();
-        cursor->setColor(color);
-        cursor->update();
-    }
-}
-
-void QQuickTextInputPrivate::hideCursor()
-{
-    if (textNode != 0 && textNode->cursorNode() != 0) {
-        QSGRectangleNode *cursor = textNode->cursorNode();
-        cursor->setColor(QColor(0, 0, 0, 0));
-        cursor->update();
-    }
-}
-
 QRectF QQuickTextInput::boundingRect() const
 {
     Q_D(const QQuickTextInput);
index 2caca45..7d9f3ff 100644 (file)
@@ -150,8 +150,6 @@ public:
 #ifndef QT_NO_IM
     Qt::InputMethodHints effectiveInputMethodHints() const;
 #endif
-    void hideCursor();
-    void showCursor();
     void handleFocusEvent(QFocusEvent *event);
 
     struct MaskInputData {
index 964dd0d..5f24668 100644 (file)
@@ -179,6 +179,14 @@ void QQuickTextNode::setCursor(const QRectF &rect, const QColor &color)
     appendChildNode(m_cursorNode);
 }
 
+void QQuickTextNode::clearCursor()
+{
+    if (m_cursorNode)
+        removeChildNode(m_cursorNode);
+    delete m_cursorNode;
+    m_cursorNode = 0;
+}
+
 void QQuickTextNode::initEngine(const QColor& textColor, const QColor& selectedTextColor, const QColor& selectionColor, const QColor& anchorColor, const QPointF &position)
 {
     m_engine.reset(new QQuickTextNodeEngine);
index fef17ae..7f9cd77 100644 (file)
@@ -88,6 +88,7 @@ public:
                          int selectionStart = -1, int selectionEnd = -1);
 
     void setCursor(const QRectF &rect, const QColor &color);
+    void clearCursor();
     QSGRectangleNode *cursorNode() const { return m_cursorNode; }
 
     QSGGlyphNode *addGlyphs(const QPointF &position, const QGlyphRun &glyphs, const QColor &color,