Krita Source Code Documentation
Loading...
Searching...
No Matches
KisTouchHoldEventsPostponer.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2026 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <QTimer>
10#include <QTouchEvent>
11
12#include <kis_assert.h>
14
15#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
16#include <KoPointerEvent.h>
17#endif
18
19#ifdef Q_OS_WIN
20// to detect if we are running in a unittest mode
21#include <QStandardPaths>
22#endif
23
24
25KisTouchHoldEventsPostponer::KisTouchHoldEventsPostponer(qreal maxHoldDistance, int holdTimeout)
26 : m_maxHoldDistance(maxHoldDistance)
27{
28 connect(&m_timer, &QTimer::timeout, this, &KisTouchHoldEventsPostponer::slotHoldCompletionTimeout);
29
30 m_timer.setSingleShot(true);
31#ifdef Q_OS_WIN
32 // on Windows, the coarse timers are too coarse for running is a unitest, so we should
33 // switch to a precise one inside unittests; for normal user-facing runs the precision
34 // is not necessary
35 m_timer.setTimerType(QStandardPaths::isTestModeEnabled() ? Qt::PreciseTimer : Qt::CoarseTimer);
36#else
37 m_timer.setTimerType(Qt::CoarseTimer);
38#endif
39 m_timer.setInterval(holdTimeout);
40 m_timer.start();
41}
42
47
52
54{
56
57 if (qualifyForPostponing(event)) {
58 enqueueEvent(event);
59 } else {
60 // enqueue the event to make sure it is delivered via
61 // the "deliver all the postponed events" mechanism
62 enqueueEvent(event);
64 }
65}
66
72
78
80{
81 // it might happen that the timer event has been emitted before
82 // a cancellation touch event was delivered, then the timer event
83 // may come "late"
84 if (m_state != WaitingForHold) {
85 // the caller should have processed all the postponed events in this case
87 return;
88 }
89
91 Q_EMIT sigHoldCompleted();
92}
93
95{
97 if (numPressedPoints > 1)
98 return false;
99
101 if (pressDistance > m_maxHoldDistance)
102 return false;
103
104 return true;
105}
106
108{
109#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
110 // TODO: change QScopedPointer -> std::unique_ptr
111 QScopedPointer<QEvent> clonedTouchEvent;
112 KoPointerEvent::copyQtPointerEvent(event, clonedTouchEvent);
113 m_postponedEvents.append(static_cast<QTouchEvent *>(clonedTouchEvent.take()));
114#else
115 m_postponedEvents.append(static_cast<QTouchEvent *>(event->clone()));
116#endif
117}
@ HoldCompleted
the postponer is still accumulating the events
@ HoldCancelled
the hold action has been detected, the accumulated events should be dropped and the hold action shoul...
QVector< QTouchEvent * > m_postponedEvents
bool qualifyForPostponing(QTouchEvent *event)
KisTouchHoldEventsPostponer(qreal maxHoldDistance, int holdTimeout)
QVector< QTouchEvent * > postponedEvents()
static Qt::TouchPointStates pressedOnlyTouchStates()
static qreal touchDragDistance(const QTouchEvent *event, Qt::TouchPointStates allowedStates)
static int countTouchPoints(const QTouchEvent *event, Qt::TouchPointStates allowedStates)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130