summaryrefslogtreecommitdiffstats
path: root/src/widgets/graphicsview/qgraphicsscene.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2018-09-26 17:36:04 +0200
committerUlf Hermann <ulf.hermann@qt.io>2018-10-04 07:00:21 +0000
commit21355b3630882932be940a48a88d8c40cf7ebf63 (patch)
tree7228a7b44299f02a500f7502db509e84d262e290 /src/widgets/graphicsview/qgraphicsscene.cpp
parentd37d8e962a1b9e83800d17207c78bc87f7d64c31 (diff)
QGraphicsScene: Make focusing on touchBegin optional
Usually we focus in when we receive a click or equivalent. QGraphicsScene by default also transfers the focus when you start a touch on a trackpad or similar. Most of the time this also generates a synthetic mouse click, so people don't necessary notice. However, at least on macOS you can configure this behavior. With focusOnTouch switched off, QGraphicsScene behaves as one would expect on macOS. Fixes: QTBUG-59442 Change-Id: Ib87112640eef6b77892ad2490d80eedd055e6dce Reviewed-by: Paul Wicking <paul.wicking@qt.io> Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src/widgets/graphicsview/qgraphicsscene.cpp')
-rw-r--r--src/widgets/graphicsview/qgraphicsscene.cpp91
1 files changed, 65 insertions, 26 deletions
diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp
index 37af4ecda0..bba992144d 100644
--- a/src/widgets/graphicsview/qgraphicsscene.cpp
+++ b/src/widgets/graphicsview/qgraphicsscene.cpp
@@ -297,6 +297,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
painterStateProtection(true),
sortCacheEnabled(false),
allItemsIgnoreTouchEvents(true),
+ focusOnTouch(true),
minimumRenderSize(0.0),
selectionChanging(0),
rectAdjust(2),
@@ -2393,6 +2394,7 @@ void QGraphicsScene::clear()
d->allItemsIgnoreHoverEvents = true;
d->allItemsUseDefaultCursor = true;
d->allItemsIgnoreTouchEvents = true;
+ d->focusOnTouch = true;
}
/*!
@@ -5854,6 +5856,41 @@ void QGraphicsScene::setMinimumRenderSize(qreal minSize)
update();
}
+/*!
+ \property QGraphicsScene::focusOnTouch
+ \since 5.12
+ \brief whether items gain focus when receiving a \e {touch begin} event.
+
+ The usual behavior is to transfer focus only when an item is clicked. Often
+ a tap on a touchpad is interpreted as equivalent to a mouse click by the
+ operating system, generating a synthesized click event in response. However,
+ at least on macOS you can configure this behavior.
+
+ By default, QGraphicsScene also transfers focus when you touch on a trackpad
+ or similar. If the operating system is configured to not generate a
+ synthetic mouse click on tapping the trackpad, this is surprising. If the
+ operating system does generate synthetic mouse clicks on tapping the
+ trackpad, the focus transfer on starting a touch gesture is unnecessary.
+
+ With focusOnTouch switched off, QGraphicsScene behaves as one would expect
+ on macOS.
+
+ The default value is \c true, ensuring that the default behavior is just as
+ in Qt versions prior to 5.12. Set to \c false to prevent touch events from
+ triggering focus changes.
+*/
+bool QGraphicsScene::focusOnTouch() const
+{
+ Q_D(const QGraphicsScene);
+ return d->focusOnTouch;
+}
+
+void QGraphicsScene::setFocusOnTouch(bool enabled)
+{
+ Q_D(QGraphicsScene);
+ d->focusOnTouch = enabled;
+}
+
void QGraphicsScenePrivate::addView(QGraphicsView *view)
{
views << view;
@@ -6033,39 +6070,41 @@ bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEve
{
Q_Q(QGraphicsScene);
- if (cachedItemsUnderMouse.isEmpty() || cachedItemsUnderMouse.constFirst() != origin) {
- const QTouchEvent::TouchPoint &firstTouchPoint = touchEvent->touchPoints().first();
- cachedItemsUnderMouse = itemsAtPosition(firstTouchPoint.screenPos().toPoint(),
- firstTouchPoint.scenePos(),
- static_cast<QWidget *>(touchEvent->target()));
- }
+ if (focusOnTouch) {
+ if (cachedItemsUnderMouse.isEmpty() || cachedItemsUnderMouse.constFirst() != origin) {
+ const QTouchEvent::TouchPoint &firstTouchPoint = touchEvent->touchPoints().first();
+ cachedItemsUnderMouse = itemsAtPosition(firstTouchPoint.screenPos().toPoint(),
+ firstTouchPoint.scenePos(),
+ static_cast<QWidget *>(touchEvent->target()));
+ }
- // Set focus on the topmost enabled item that can take focus.
- bool setFocus = false;
+ // Set focus on the topmost enabled item that can take focus.
+ bool setFocus = false;
- foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
- if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) {
- if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) {
+ foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
+ if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) {
+ if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) {
+ setFocus = true;
+ if (item != q->focusItem())
+ q->setFocusItem(item, Qt::MouseFocusReason);
+ break;
+ }
+ }
+ if (item->isPanel())
+ break;
+ if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
+ break;
+ if (item->d_ptr->flags & QGraphicsItem::ItemStopsFocusHandling) {
+ // Make sure we don't clear focus.
setFocus = true;
- if (item != q->focusItem())
- q->setFocusItem(item, Qt::MouseFocusReason);
break;
}
}
- if (item->isPanel())
- break;
- if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
- break;
- if (item->d_ptr->flags & QGraphicsItem::ItemStopsFocusHandling) {
- // Make sure we don't clear focus.
- setFocus = true;
- break;
- }
- }
- // If nobody could take focus, clear it.
- if (!stickyFocus && !setFocus)
- q->setFocusItem(0, Qt::MouseFocusReason);
+ // If nobody could take focus, clear it.
+ if (!stickyFocus && !setFocus)
+ q->setFocusItem(0, Qt::MouseFocusReason);
+ }
bool res = false;
bool eventAccepted = touchEvent->isAccepted();