From 1b5bc9723c0b23ca5197097c3087df6bbe024a2a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 19 Apr 2016 10:15:54 +0200 Subject: QWidgetLineControl: respect run-time changes to cursorFlashTime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cursorFlashTime will now change dynamically from QPA while platform controlled text selection (on mobile) is ongoing. This patch will therefore update QWidgetLineControl so that it listens to the cursorFlashTimeChanged signal and changes the blinking rate when triggered. The previous code had a function setBlinkingRate, which is now changed to setBlinkingCursorEnabled (like in QWidgetTextControl). This is because all callers of the function did either pass "QApplication::cursorFlashTime" or "0", which basically means enable or disable blinking. This moves the control of the blinking rate fully to QWidgetLineControl, which simplifies the code a bit, especially when cursorFlashTime can change. Note that when setting a blink period to 0, it means "show the cursor without blinking". AFAICS, the current implementation did not guarantee that. This is now made more explicit in the code. If hiding the cursor is needed, a separate function "setCursorVisible" is already available for controlling that. Change-Id: I7d39882de192a23e6e7ba370749892c7702c3d3b Reviewed-by: Jan Arve Sæther --- src/widgets/widgets/qlineedit.cpp | 14 ++++---- src/widgets/widgets/qwidgetlinecontrol.cpp | 51 ++++++++++++++++++++---------- src/widgets/widgets/qwidgetlinecontrol_p.h | 8 ++--- 3 files changed, 45 insertions(+), 28 deletions(-) diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 3a04343108..7ccf28034b 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -1423,11 +1423,11 @@ bool QLineEdit::event(QEvent * e) d->control->processShortcutOverrideEvent(ke); #endif } else if (e->type() == QEvent::KeyRelease) { - d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime()); + d->control->updateCursorBlinking(); } else if (e->type() == QEvent::Show) { //In order to get the cursor blinking if QComboBox::setEditable is called when the combobox has focus if (hasFocus()) { - d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime()); + d->control->setBlinkingCursorEnabled(true); QStyleOptionFrame opt; initStyleOption(&opt); if ((!hasSelectedText() && d->control->preeditAreaText().isEmpty()) @@ -1444,10 +1444,10 @@ bool QLineEdit::event(QEvent * e) if (e->type() == QEvent::EnterEditFocus) { end(false); d->setCursorVisible(true); - d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime()); + d->control->setCursorBlinkEnabled(true); } else if (e->type() == QEvent::LeaveEditFocus) { d->setCursorVisible(false); - d->control->setCursorBlinkPeriod(0); + d->control->setCursorBlinkEnabled(false); if (d->control->hasAcceptableInput() || d->control->fixup()) emit editingFinished(); } @@ -1694,7 +1694,7 @@ void QLineEdit::keyPressEvent(QKeyEvent *event) if (event->isAccepted()) { if (layoutDirection() != d->control->layoutDirection()) setLayoutDirection(d->control->layoutDirection()); - d->control->setCursorBlinkPeriod(0); + d->control->updateCursorBlinking(); } } @@ -1806,7 +1806,7 @@ void QLineEdit::focusInEvent(QFocusEvent *e) #ifdef QT_KEYPAD_NAVIGATION if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && ( e->reason() == Qt::PopupFocusReason))) { #endif - d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime()); + d->control->setBlinkingCursorEnabled(true); QStyleOptionFrame opt; initStyleOption(&opt); if((!hasSelectedText() && d->control->preeditAreaText().isEmpty()) @@ -1850,7 +1850,7 @@ void QLineEdit::focusOutEvent(QFocusEvent *e) deselect(); d->setCursorVisible(false); - d->control->setCursorBlinkPeriod(0); + d->control->setBlinkingCursorEnabled(false); #ifdef QT_KEYPAD_NAVIGATION // editingFinished() is already emitted on LeaveEditFocus if (!QApplication::keypadNavigationEnabled()) diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp index 24edca172b..86903dc0c3 100644 --- a/src/widgets/widgets/qwidgetlinecontrol.cpp +++ b/src/widgets/widgets/qwidgetlinecontrol.cpp @@ -636,7 +636,7 @@ void QWidgetLineControl::draw(QPainter *painter, const QPoint &offset, const QRe o.format.setForeground(m_palette.brush(QPalette::HighlightedText)); } else { // mask selection - if(!m_blinkPeriod || m_blinkStatus){ + if (m_blinkStatus){ o.start = m_cursor; o.length = 1; o.format.setBackground(m_palette.brush(QPalette::Text)); @@ -653,7 +653,7 @@ void QWidgetLineControl::draw(QPainter *painter, const QPoint &offset, const QRe int cursor = m_cursor; if (m_preeditCursor != -1) cursor += m_preeditCursor; - if (!m_hideCursor && (!m_blinkPeriod || m_blinkStatus)) + if (!m_hideCursor && m_blinkStatus) textLayout()->drawCursor(painter, offset, cursor, m_cursorWidth); } } @@ -1486,38 +1486,55 @@ void QWidgetLineControl::complete(int key) void QWidgetLineControl::setReadOnly(bool enable) { + if (m_readOnly == enable) + return; + m_readOnly = enable; + updateCursorBlinking(); +} + +void QWidgetLineControl::setBlinkingCursorEnabled(bool enable) +{ + if (m_blinkEnabled == enable) + return; + + m_blinkEnabled = enable; + if (enable) - setCursorBlinkPeriod(0); + connect(qApp->styleHints(), &QStyleHints::cursorFlashTimeChanged, this, &QWidgetLineControl::updateCursorBlinking); else - setCursorBlinkPeriod(QApplication::cursorFlashTime()); + disconnect(qApp->styleHints(), &QStyleHints::cursorFlashTimeChanged, this, &QWidgetLineControl::updateCursorBlinking); + + updateCursorBlinking(); } -void QWidgetLineControl::setCursorBlinkPeriod(int msec) +void QWidgetLineControl::updateCursorBlinking() { - if (msec == m_blinkPeriod) - return; if (m_blinkTimer) { killTimer(m_blinkTimer); - } - if (msec > 0 && !m_readOnly) { - m_blinkTimer = startTimer(msec / 2); - m_blinkStatus = 1; - } else { m_blinkTimer = 0; - if (m_blinkStatus == 1) - emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect()); } - m_blinkPeriod = msec; + + if (m_blinkEnabled && !m_readOnly) { + int flashTime = QGuiApplication::styleHints()->cursorFlashTime(); + if (flashTime >= 2) + m_blinkTimer = startTimer(flashTime / 2); + } + + m_blinkStatus = 1; + emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect()); } // This is still used by QDeclarativeTextInput in the qtquick1 repo void QWidgetLineControl::resetCursorBlinkTimer() { - if (m_blinkPeriod == 0 || m_blinkTimer == 0) + if (!m_blinkEnabled || m_blinkTimer == 0) return; killTimer(m_blinkTimer); - m_blinkTimer = startTimer(m_blinkPeriod / 2); + m_blinkTimer = 0; + int flashTime = QGuiApplication::styleHints()->cursorFlashTime(); + if (flashTime >= 2) + m_blinkTimer = startTimer(flashTime / 2); m_blinkStatus = 1; } diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h index 8b723b0224..34d19d1e77 100644 --- a/src/widgets/widgets/qwidgetlinecontrol_p.h +++ b/src/widgets/widgets/qwidgetlinecontrol_p.h @@ -83,7 +83,7 @@ public: : m_cursor(0), m_preeditCursor(0), m_cursorWidth(0), m_layoutDirection(Qt::LayoutDirectionAuto), m_hideCursor(false), m_separator(0), m_readOnly(0), m_dragEnabled(0), m_echoMode(0), m_textDirty(0), m_selDirty(0), - m_validInput(1), m_blinkStatus(0), m_blinkPeriod(0), m_blinkTimer(0), m_deleteAllTimer(0), + m_validInput(1), m_blinkStatus(0), m_blinkEnabled(false), m_blinkTimer(0), m_deleteAllTimer(0), m_ascent(0), m_maxLength(32767), m_lastCursorPos(-1), m_tripleClickTimer(0), m_maskData(0), m_modifiedState(0), m_undoState(0), m_selstart(0), m_selend(0), m_passwordEchoEditing(false) @@ -354,8 +354,8 @@ public: void processInputMethodEvent(QInputMethodEvent *event); void processKeyEvent(QKeyEvent* ev); - int cursorBlinkPeriod() const { return m_blinkPeriod; } - void setCursorBlinkPeriod(int msec); + void setBlinkingCursorEnabled(bool enable); + void updateCursorBlinking(); void resetCursorBlinkTimer(); bool cursorBlinkStatus() const { return m_blinkStatus; } @@ -433,7 +433,7 @@ private: uint m_selDirty : 1; uint m_validInput : 1; uint m_blinkStatus : 1; - int m_blinkPeriod; // 0 for non-blinking cursor + uint m_blinkEnabled : 1; int m_blinkTimer; int m_deleteAllTimer; int m_ascent; -- cgit v1.2.3