aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquicktextedit.cpp
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2022-02-24 20:40:14 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2022-07-23 00:37:07 +0200
commit90d3fac73a10b9363fd34e6757cc730d7a0c086c (patch)
treedb03aae65be7e727b218a6a3a821424d24546eeb /src/quick/items/qquicktextedit.cpp
parentc2805daaa58f222d6d19ac939c78e981ba907867 (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.cpp60
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"
+