QWidgetLineControl: respect run-time changes to cursorFlashTime

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 <jan-arve.saether@theqtcompany.com>
This commit is contained in:
Richard Moe Gustavsen 2016-04-19 10:15:54 +02:00
parent e36f03f97a
commit 1b5bc9723c
3 changed files with 46 additions and 29 deletions

View File

@ -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())

View File

@ -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;
if (enable)
setCursorBlinkPeriod(0);
else
setCursorBlinkPeriod(QApplication::cursorFlashTime());
updateCursorBlinking();
}
void QWidgetLineControl::setCursorBlinkPeriod(int msec)
void QWidgetLineControl::setBlinkingCursorEnabled(bool enable)
{
if (msec == m_blinkPeriod)
if (m_blinkEnabled == enable)
return;
m_blinkEnabled = enable;
if (enable)
connect(qApp->styleHints(), &QStyleHints::cursorFlashTimeChanged, this, &QWidgetLineControl::updateCursorBlinking);
else
disconnect(qApp->styleHints(), &QStyleHints::cursorFlashTimeChanged, this, &QWidgetLineControl::updateCursorBlinking);
updateCursorBlinking();
}
void QWidgetLineControl::updateCursorBlinking()
{
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;
}

View File

@ -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;