aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquicktextcontrol.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/qquicktextcontrol.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/qquicktextcontrol.cpp')
-rw-r--r--src/quick/items/qquicktextcontrol.cpp25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index 40c9e21dc4..cbc9f10f9e 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -36,6 +36,7 @@
#include <qmetaobject.h>
#include <private/qqmlglobal_p.h>
+#include <private/qquickdeliveryagent_p_p.h>
// ### these should come from QStyleHints
const int textCursorWidth = 1;
@@ -79,6 +80,7 @@ QQuickTextControlPrivate::QQuickTextControlPrivate()
hasImState(false),
cursorRectangleChanged(false),
hoveredMarker(false),
+ selectByTouchDrag(false),
lastSelectionStart(-1),
lastSelectionEnd(-1)
{}
@@ -1004,6 +1006,9 @@ void QQuickTextControlPrivate::mousePressEvent(QMouseEvent *e, const QPointF &po
cursor.clearSelection();
}
}
+
+ if (!selectByTouchDrag && !QQuickDeliveryAgentPrivate::isEventFromMouseOrTouchpad(e))
+ return;
if (interactionFlags & Qt::TextEditable)
blockWithMarkerUnderMousePress = q->blockWithMarkerAt(pos);
if (e->button() & Qt::MiddleButton) {
@@ -1074,6 +1079,9 @@ void QQuickTextControlPrivate::mousePressEvent(QMouseEvent *e, const QPointF &po
void QQuickTextControlPrivate::mouseMoveEvent(QMouseEvent *e, const QPointF &mousePos)
{
+ if (!selectByTouchDrag && !QQuickDeliveryAgentPrivate::isEventFromMouseOrTouchpad(e))
+ return;
+
Q_Q(QQuickTextControl);
if ((e->buttons() & Qt::LeftButton)) {
@@ -1154,6 +1162,7 @@ void QQuickTextControlPrivate::mouseReleaseEvent(QMouseEvent *e, const QPointF &
const QTextCursor oldSelection = cursor;
const int oldCursorPos = cursor.position();
+ const bool isMouse = QQuickDeliveryAgentPrivate::isEventFromMouseOrTouchpad(e);
if (mousePressed) {
mousePressed = false;
@@ -1169,6 +1178,8 @@ void QQuickTextControlPrivate::mouseReleaseEvent(QMouseEvent *e, const QPointF &
q->insertFromMimeData(md);
#endif
}
+ if (!isMouse && !selectByTouchDrag && interactionFlags.testFlag(Qt::TextEditable))
+ setCursorPosition(pos);
repaintOldAndNewSelection(oldSelection);
@@ -1177,7 +1188,8 @@ void QQuickTextControlPrivate::mouseReleaseEvent(QMouseEvent *e, const QPointF &
q->updateCursorRectangle(true);
}
- if ((interactionFlags & Qt::TextEditable) && (e->button() & Qt::LeftButton) && blockWithMarkerUnderMousePress.isValid()) {
+ if ((isMouse || selectByTouchDrag) && interactionFlags.testFlag(Qt::TextEditable) &&
+ (e->button() & Qt::LeftButton) && blockWithMarkerUnderMousePress.isValid()) {
QTextBlock block = q->blockWithMarkerAt(pos);
if (block == blockWithMarkerUnderMousePress) {
auto fmt = block.blockFormat();
@@ -1215,7 +1227,8 @@ void QQuickTextControlPrivate::mouseDoubleClickEvent(QMouseEvent *e, const QPoin
{
Q_Q(QQuickTextControl);
- if (e->button() == Qt::LeftButton && (interactionFlags & Qt::TextSelectableByMouse)) {
+ if (e->button() == Qt::LeftButton && (interactionFlags & Qt::TextSelectableByMouse)
+ && (selectByTouchDrag || QQuickDeliveryAgentPrivate::isEventFromMouseOrTouchpad(e))) {
#if QT_CONFIG(im)
commitPreedit();
#endif
@@ -1609,6 +1622,14 @@ void QQuickTextControl::setWordSelectionEnabled(bool enabled)
d->wordSelectionEnabled = enabled;
}
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
+void QQuickTextControl::setTouchDragSelectionEnabled(bool enabled)
+{
+ Q_D(QQuickTextControl);
+ d->selectByTouchDrag = enabled;
+}
+#endif
+
QMimeData *QQuickTextControl::createMimeDataFromSelection() const
{
Q_D(const QQuickTextControl);