diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2022-02-24 20:40:14 +0100 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2022-07-23 00:37:07 +0200 |
commit | 90d3fac73a10b9363fd34e6757cc730d7a0c086c (patch) | |
tree | db03aae65be7e727b218a6a3a821424d24546eeb /src/quick/items/qquicktextedit.cpp | |
parent | c2805daaa58f222d6d19ac939c78e981ba907867 (diff) |
TextEdit: selectByMouse default=true, but not on touchscreens
When you drag a finger across a TextEdit, it should not select text.
- your finger probably covers several characters, so you can't see where
you're selecting until afterwards
- if the item is in a Flickable, flicking by touch should be prioritized
- if flicking happens, the text cursor should not move; but to avoid
losing too much functionality, we allow it to move on release, if
the TextEdit gets the release (i.e. if it still has the exclusive
grab)
So now we distinguish mouse events that are synthesized from non-mouse
devices and avoid mouse-like behaviors as described above, but there is
no behavior change if the event comes from an actual mouse or touchpad.
Since most users want selecting text by mouse to "just work", and an
actual mouse is precise enough to do so, and dragging a Flickable with
the mouse is unintuitive (since most UIs don't allow it and most mice
have wheels), selectByMouse now defaults to true, and has the stricter
meaning that its name implies. To select text on a touchscreen, the
end-user needs to rely on text-selection handles, which are provided on
touch-centric mobile platforms, and could also be implemented from
scratch if someone builds a custom text field using TextInput.
In QQuickPressHandler::mousePressEvent() we give the original event's
device to the delayed press event, now that we check the device to
distinguish "real" mouse events from those that are synthesized from
touch.
[ChangeLog][QtQuick][TextEdit] The selectByMouse property is now enabled
by default, but no longer enables selecting by dragging your finger
across text on a touchscreen. Platforms that are optimized for
touchscreens normally use special text-selection handles, which interact
with Qt via QInputMethod. You can opt out of the behavior change by
using an import version < 6.4.
Pick-to: 6.4
Task-number: QTBUG-10684
Task-number: QTBUG-38934
Task-number: QTBUG-90494
Task-number: QTBUG-101205
Change-Id: Ia96f53cd7c6db5f995aab5505f61c13f9a4c4c0a
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/quick/items/qquicktextedit.cpp')
-rw-r--r-- | src/quick/items/qquicktextedit.cpp | 60 |
1 files changed, 50 insertions, 10 deletions
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index 9ee833fddc..8ce622d176 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -31,6 +31,7 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcVP) +Q_LOGGING_CATEGORY(lcTextEdit, "qt.quick.textedit") /*! \qmltype TextEdit @@ -68,9 +69,12 @@ TextEdit { A particular look and feel might use smooth scrolling (eg. using SmoothedAnimation), might have a visible scrollbar, or a scrollbar that fades in to show location, etc. - Clipboard support is provided by the cut(), copy(), and paste() functions, and the selection can - be handled in a traditional "mouse" mechanism by setting selectByMouse, or handled completely - from QML by manipulating selectionStart and selectionEnd, or using selectAll() or selectWord(). + Clipboard support is provided by the cut(), copy(), and paste() functions. + Text can be selected by mouse in the usual way, unless \l selectByMouse is + set to \c false; and by keyboard with the \c {Shift+arrow} key + combinations, unless \l selectByKeyboard is set to \c false. To select text + programmatically, you can set the \l selectionStart and \l selectionEnd + properties, or use \l selectAll() or \l selectWord(). You can translate between cursor positions (characters from the start of the document) and pixel points using positionAt() and positionToRectangle(). @@ -1568,12 +1572,25 @@ void QQuickTextEdit::setSelectByKeyboard(bool on) /*! \qmlproperty bool QtQuick::TextEdit::selectByMouse - Defaults to false. - - If true, the user can use the mouse to select text in some - platform-specific way. Note that for some platforms this may - not be an appropriate interaction; it may conflict with how - the text needs to behave inside a Flickable, for example. + Defaults to \c true since Qt 6.4. + + If \c true, the user can use the mouse to select text in the usual way. + + \note In versions prior to 6.4, the default was \c false; but if you + enabled this property, you could also select text on a touchscreen by + dragging your finger across it. This interfered with flicking when TextEdit + was used inside a Flickable. However, Qt has supported text selection + handles on mobile platforms, and on embedded platforms using Qt Virtual + Keyboard, since version 5.7, via QInputMethod. Most users would be + surprised if finger dragging selected text rather than flicking the parent + Flickable. Therefore, selectByMouse now really means what it says: if + \c true, you can select text by dragging \e only with a mouse, whereas + the platform is expected to provide selection handles on touchscreens. + If this change does not suit your application, you can set \c selectByMouse + to \c false, or import an older API version (for example + \c {import QtQuick 6.3}) to revert to the previous behavior. The option to + revert behavior by changing the import version will be removed in a later + version of Qt. */ bool QQuickTextEdit::selectByMouse() const { @@ -1911,6 +1928,8 @@ Handles the given mouse \a event. void QQuickTextEdit::mousePressEvent(QMouseEvent *event) { Q_D(QQuickTextEdit); + const bool isMouse = QQuickDeliveryAgentPrivate::isEventFromMouseOrTouchpad(event); + setKeepMouseGrab(d->selectByMouse && isMouse); d->control->processEvent(event, QPointF(-d->xoff, -d->yoff)); if (d->focusOnPress){ bool hadActiveFocus = hasActiveFocus(); @@ -2425,9 +2444,10 @@ void QQuickTextEditPrivate::init() document = new QQuickTextDocumentWithImageResources(q); control = new QQuickTextControl(document, q); - control->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard | Qt::TextEditable); + control->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard | Qt::TextEditable); control->setAcceptRichText(false); control->setCursorIsFocusIndicator(true); + q->setKeepMouseGrab(true); qmlobject_connect(control, QQuickTextControl, SIGNAL(updateCursorRequest()), q, QQuickTextEdit, SLOT(updateCursor())); qmlobject_connect(control, QQuickTextControl, SIGNAL(selectionChanged()), q, QQuickTextEdit, SIGNAL(selectedTextChanged())); @@ -3337,6 +3357,26 @@ void QQuickTextEdit::clear() d->control->clear(); } +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) +void QQuickTextEdit::setOldSelectionDefault() +{ + Q_D(QQuickTextEdit); + d->selectByMouse = false; + setKeepMouseGrab(false); + d->control->setTextInteractionFlags(d->control->textInteractionFlags() & ~Qt::TextSelectableByMouse); + d->control->setTouchDragSelectionEnabled(true); + qCDebug(lcTextEdit, "pre-6.4 behavior chosen by import version: selectByMouse defaults false; if enabled, touchscreen acts like a mouse"); +} + +// TODO in 6.7.0: remove the note about versions prior to 6.4 in selectByMouse() documentation +QQuickPre64TextEdit::QQuickPre64TextEdit(QQuickItem *parent) + : QQuickTextEdit(parent) +{ + setOldSelectionDefault(); +} +#endif + QT_END_NAMESPACE #include "moc_qquicktextedit_p.cpp" + |