12#include <QTabletEvent>
25#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
28#include <QtGui/private/qeventpoint_p.h>
33 auto action = shortcut->
action();
34 return QString(
"%1/%2").arg(action->name()).arg(action->shortcutIndexes().key(shortcut->
shortcutIndex(),
"<unknown>"));
37#define DEBUG_ACTION(text) dbgInputMatcher << __FUNCTION__ << "-" << text;
38#define DEBUG_SHORTCUT(text, shortcut) dbgInputMatcher << __FUNCTION__ << "-" << text << "act:" << debugShortcutName(shortcut);
39#define DEBUG_KEY(text) dbgInputMatcher << __FUNCTION__ << "-" << text << "keys:" << m_d->keys;
40#define DEBUG_BUTTON_ACTION(text, button) dbgInputMatcher << __FUNCTION__ << "-" << text << "button:" << button << "btns:" << m_d->buttons << "keys:" << m_d->keys;
41#define DEBUG_EVENT_ACTION(text, event) if (event) {dbgInputMatcher << __FUNCTION__ << "-" << text << "type:" << event->type();}
42#define DEBUG_TOUCH_ACTION(text, event) \
44 dbgInputMatcher << __FUNCTION__ << "-" << text << "type:" << event->type() \
45 << "tps:" << KisTouchShortcut::countTouchPoints(event, KisTouchShortcut::allTouchStates()) \
46 << "pressedTps:" << KisTouchShortcut::countTouchPoints(event, KisTouchShortcut::pressedOnlyTouchStates()) \
47 << "maxTps:" << m_d->maxTouchPoints << "drag:" << m_d->isTouchDragDetected; \
53QTouchEvent generateFakeTouchEndEvent(
const QTouchEvent *event)
55#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
56 auto points =
event->touchPoints();
58 auto points =
event->points();
61 for (
auto it = points.begin(); it != points.end();) {
62#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
63 if (it->state() == Qt::TouchPointReleased) {
64 it = points.erase(it);
66 it->setState(Qt::TouchPointReleased);
70 if (it->state() == QEventPoint::Released) {
71 it = points.erase(it);
73 QMutableEventPoint::setState(*it, QEventPoint::Released);
79#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
80 return QTouchEvent(QEvent::TouchEnd, event->device(), event->modifiers(), Qt::TouchPointReleased, points);
82 return QTouchEvent(QEvent::TouchEnd, event->pointingDevice(), event->modifiers(), points);
96 , nativeGestureShortcut(0)
97 , touchpadScrollShortcut(0)
99 , suppressAllActions(
false)
100 , suppressAllKeyboardActions(
false)
101 , cursorEntered(
false)
106 qDeleteAll(singleActionShortcuts);
107 qDeleteAll(strokeShortcuts);
108 qDeleteAll(touchShortcuts);
133 int maxTouchPoints{0};
134 int matchingIteration{0};
135 bool isTouchDragDetected {
false};
136 bool isTouchHeld {
false};
139 bool touchActionTracked {
false};
140 int touchHoldDelayMs {400};
151 int lastRawTouchPointsCount = 0;
160 int recursiveCounter = 0;
161 int brokenByRecursion = 0;
168 q->m_d->recursiveCounter++;
169 q->m_d->brokenByRecursion++;
173 q->m_d->recursiveCounter--;
177 return q->m_d->recursiveCounter > 1;
187 q->m_d->brokenByRecursion = 0;
194 return q->m_d->brokenByRecursion > 0;
202 return suppressAllActions || !cursorEntered;
205 return suppressAllActions;
210 return suppressAllActions;
214 return suppressAllKeyboardActions;
229 return m_d->runningShortcut ||
m_d->touchShortcut ||
m_d->nativeGestureShortcut ||
m_d->touchpadScrollShortcut;
235 if (shortcut->isHoldType() && shortcut->isAvailable(
m_d->actionGroupMask())) {
244 m_d->singleActionShortcuts.append(shortcut);
249 m_d->strokeShortcuts.append(shortcut);
254 m_d->touchShortcuts.append(shortcut);
259 m_d->nativeGestureShortcuts.append(shortcut);
264 m_d->touchpadScrollShortcuts.append(shortcut);
269 return (
m_d->runningShortcut &&
m_d->runningShortcut->action()
270 &&
m_d->runningShortcut->action()->supportsHiResInputEvents(
m_d->runningShortcut->shortcutIndex()))
271 || (
m_d->touchShortcut &&
m_d->touchShortcut->action()
272 &&
m_d->touchShortcut->action()->supportsHiResInputEvents(
m_d->touchShortcut->shortcutIndex()))
273 || (
m_d->nativeGestureShortcut &&
m_d->nativeGestureShortcut->action()
274 &&
m_d->nativeGestureShortcut->action()->supportsHiResInputEvents(
m_d->nativeGestureShortcut->shortcutIndex()))
275 || (
m_d->touchpadScrollShortcut &&
m_d->touchpadScrollShortcut->action()
276 &&
m_d->touchpadScrollShortcut->action()->supportsHiResInputEvents(
m_d->touchpadScrollShortcut->shortcutIndex()));
281 Private::RecursionNotifier notifier(
this);
285 if (
m_d->keys.contains(key)) {
DEBUG_ACTION(
"Peculiar, records show key was already pressed"); }
291 m_d->keys.insert(key);
294 if (notifier.isInRecursion()) {
306 Private::RecursionNotifier notifier(
this);
311 if (!
m_d->keys.contains(key)) {
DEBUG_ACTION(
"Peculiar, autorepeated key but can't remember it was pressed"); }
313 if (
m_d->polledKeys.contains(key)) {
314 m_d->polledKeys.remove(key);
317 if (notifier.isInRecursion()) {
321 QSet<Qt::Key> filteredKeys =
m_d->keys;
322 filteredKeys.remove(key);
331 Private::RecursionNotifier notifier(
this);
333 if (!
m_d->keys.contains(key)) {
DEBUG_ACTION(
"Peculiar, key released but can't remember it was pressed"); }
334 else m_d->keys.remove(key);
336 m_d->polledKeys.remove(key);
340 if (notifier.isInRecursion()) {
352 Private::RecursionNotifier notifier(
this);
370 if (notifier.isInRecursion()) {
382 Private::RecursionNotifier notifier(
this);
388 if (
m_d->runningShortcut) {
395 if (!
m_d->buttons.contains(
button))
reset(
"Peculiar, button released but we can't remember it was pressed");
398 if (notifier.isInRecursion()) {
410 Private::RecursionNotifier notifier(
this);
423 Private::RecursionNotifier notifier(
this);
425 if (notifier.isInRecursion()) {
431 if (
m_d->runningShortcut) {
433 m_d->runningShortcut->action()->inputEvent(event);
442 Private::RecursionNotifier notifier(
this);
444 m_d->cursorEntered =
true;
446 if (notifier.isInRecursion()) {
456 Private::RecursionNotifier notifier(
this);
458 m_d->cursorEntered =
false;
460 if (notifier.isInRecursion()) {
472 Private::RecursionNotifier notifier(
this);
475 DEBUG_ACTION(
"touch action rejected by a running shortcut");
479 return !notifier.isInRecursion();
482#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
483 QScopedPointer<QEvent>
tmp;
484 KoPointerEvent::copyQtPointerEvent(event,
tmp);
485 m_d->lastProcessedTouchEvent.reset(
static_cast<QTouchEvent*
>(
tmp.take()));
487 m_d->lastProcessedTouchEvent.reset(event->clone());
492 if (
m_d->ignoreMultiFingerCancelWorkaround) {
493 m_d->ignoreMultiFingerCancelWorkaround->lastRawTouchPointsCount =
m_d->maxTouchPoints;
495 m_d->matchingIteration = 1;
496 m_d->isTouchDragDetected =
false;
497 m_d->isTouchHeld =
false;
498 m_d->touchActionTracked =
true;
499#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
500 KoPointerEvent::copyQtPointerEvent(event,
m_d->bestCandidateForTapTouchEvent);
502 m_d->bestCandidateForTapTouchEvent.reset(event->clone());
508 QObject::connect(&
m_d->touchHoldEventPostponer.value(),
511 slotTouchHoldCompleted();
513 m_d->touchHoldEventPostponer->pushThrough(event);
515 m_d->touchHoldEventPostponer.reset();
521 return !notifier.isInRecursion();
528 if (!
m_d->touchActionTracked)
return false;
530 if (
m_d->ignoreMultiFingerCancelWorkaround) {
531 m_d->ignoreMultiFingerCancelWorkaround->lastRawTouchPointsCount =
535 if (
m_d->touchHoldEventPostponer) {
536 m_d->touchHoldEventPostponer->pushThrough(event);
541 Q_FOREACH (QTouchEvent *event,
m_d->touchHoldEventPostponer->postponedEvents()) {
542 if (event->type() == QEvent::TouchUpdate) {
546 m_d->touchHoldEventPostponer.reset();
567 QTouchEvent *
event =
m_d->touchHoldEventPostponer->postponedEvents().front();
570 m_d->isTouchHeld =
true;
581 m_d->isTouchHeld =
false;
586 m_d->touchHoldEventPostponer.reset();
591 if (
_41020().isDebugEnabled()) {
594 if (oldNumPressedPoints != newNumPressedPoints) {
599#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
600 QScopedPointer<QEvent>
tmp;
601 KoPointerEvent::copyQtPointerEvent(event,
tmp);
602 m_d->lastProcessedTouchEvent.reset(
static_cast<QTouchEvent*
>(
tmp.take()));
604 m_d->lastProcessedTouchEvent.reset(event->clone());
607 if (
m_d->isTouchHeld) {
609 m_d->touchShortcut->action()->inputEvent(event);
619 if (!
m_d->isTouchDragDetected) {
621 m_d->isTouchDragDetected =
true;
629 const int numStillDraggedPoints =
632 m_d->maxTouchPoints = numStillDraggedPoints;
634 m_d->isTouchDragDetected =
true;
642 const int numIterations = 10;
643 if (
m_d->matchingIteration <= numIterations && !
m_d->isTouchDragDetected) {
644 m_d->matchingIteration++;
651 if (
m_d->isTouchDragDetected) {
652 if (
m_d->touchShortcut
657 }
else if (
m_d->touchShortcut) {
658 m_d->touchShortcut->action()->inputEvent(event);
663#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
664 const auto FlagReleased = Qt::TouchPointReleased;
666 const auto FlagReleased = QEventPoint::Released;
672 if (previousNumPoints >=
m_d->maxTouchPoints) {
673 m_d->maxTouchPoints = previousNumPoints;
675 m_d->bestCandidateForTapTouchEvent.reset();
688 Private::RecursionNotifier notifier(
this);
694 if (!
m_d->touchActionTracked) {
697 m_d->touchHoldEventPostponer->cancelHoldWait();
698 m_d->touchHoldEventPostponer.reset();
704 if (
m_d->touchHoldEventPostponer) {
708 m_d->touchHoldEventPostponer->cancelHoldWait();
712 Q_FOREACH (QTouchEvent *event,
m_d->touchHoldEventPostponer->postponedEvents()) {
713 if (event->type() == QEvent::TouchUpdate) {
717 m_d->touchHoldEventPostponer.reset();
720 m_d->touchActionTracked =
false;
732 if (notifier.isInRecursion()) {
745 if (
m_d->touchHoldEventPostponer) {
747 m_d->touchHoldEventPostponer->cancelHoldWait();
748 m_d->touchHoldEventPostponer.reset();
752 if (
m_d->touchShortcut) {
756 m_d->touchShortcut = 0;
764 QTouchEvent touchEvent = generateFakeTouchEndEvent(
m_d->lastProcessedTouchEvent.data());
769 m_d->touchActionTracked =
false;
789 if (
m_d->ignoreMultiFingerCancelWorkaround) {
793 if (
m_d->ignoreMultiFingerCancelWorkaround->lastRawTouchPointsCount >= 3) {
794 DEBUG_ACTION(
"IgnoreMultiFingerCancelWorkaround: converting a cancelled action into a normally finished action")
800 Private::RecursionNotifier notifier(
this);
806 if (!
m_d->touchActionTracked) {
808 m_d->touchHoldEventPostponer->cancelHoldWait();
809 m_d->touchHoldEventPostponer.reset();
818 if (notifier.isInRecursion()) {
830 Private::RecursionNotifier notifier(
this);
834 return !notifier.isInRecursion();
846 else if (
m_d->nativeGestureShortcut) {
847 m_d->nativeGestureShortcut->action()->inputEvent( event );
856 Private::RecursionNotifier notifier(
this);
860 if (
m_d->nativeGestureShortcut) {
864 if (notifier.isInRecursion()) {
876 return !
m_d->touchpadScrollShortcuts.isEmpty();
881 Private::RecursionNotifier notifier(
this);
883 if (notifier.isInRecursion())
return false;
891 if (
m_d->touchpadScrollShortcut) {
892 m_d->touchpadScrollShortcut->action()->inputEvent(event);
895 return bool(
m_d->touchpadScrollShortcut);
900 Private::RecursionNotifier notifier(
this);
902 if (notifier.isInRecursion())
return false;
906 if (
m_d->touchpadScrollShortcut) {
907 m_d->touchpadScrollShortcut->action()->inputEvent(event);
910 return bool(
m_d->touchpadScrollShortcut);
915 Private::RecursionNotifier notifier(
this);
917 if (notifier.isInRecursion())
return false;
923 if (
m_d->touchpadScrollShortcut) {
927 if (notifier.isInRecursion()) {
938 Qt::MouseButtons flags;
939 Q_FOREACH (Qt::MouseButton b, list) {
947 Private::RecursionNotifier notifier(
this);
950 reset(
"reinitialize");
952 if (notifier.isInRecursion()) {
962 Private::RecursionNotifier notifier(
this);
964 m_d->buttons.clear();
967 if (notifier.isInRecursion()) {
977 Q_FOREACH (Qt::Key key,
m_d->keys) {
978 if (!
keys.contains(key)) {
983 Q_FOREACH (Qt::Key key,
keys) {
984 if (!
m_d->keys.contains(key)) {
986 m_d->polledKeys << key;
990 Private::RecursionNotifier notifier(
this);
992 if (notifier.isInRecursion()) {
1004 auto checkKey = [
this, modifiers] (Qt::Key key, Qt::KeyboardModifier modifier) {
1005 return m_d->keys.contains(key) == bool(modifiers & modifier);
1008 return checkKey(Qt::Key_Shift, Qt::ShiftModifier) &&
1009 checkKey(Qt::Key_Control, Qt::ControlModifier) &&
1010 checkKey(Qt::Key_Alt, Qt::AltModifier) &&
1011 checkKey(Qt::Key_Meta, Qt::MetaModifier);
1018 std::copy(
m_d->keys.begin(),
m_d->keys.end(), std::back_inserter(
keys));
1024 return !
m_d->polledKeys.empty();
1029 Private::RecursionNotifier notifier(
this);
1033 if (
m_d->runningShortcut) {
1050 Private::RecursionNotifier notifier(
this);
1054 if (notifier.isInRecursion()) {
1065 m_d->buttons.clear();
1073 m_d->buttons.clear();
1085 m_d->suppressedSingleActionShortcuts.clear();
1088 Q_FOREACH (
const QKeySequence &seq, shortcuts) {
1090 m_d->suppressedSingleActionShortcuts.insert(s);
1098 m_d->suppressAllKeyboardActions =
value;
1103 reset(
"Clearing shortcuts");
1105 qDeleteAll(
m_d->singleActionShortcuts);
1106 m_d->singleActionShortcuts.clear();
1107 m_d->suppressedSingleActionShortcuts.clear();
1109 qDeleteAll(
m_d->strokeShortcuts);
1110 m_d->strokeShortcuts.clear();
1112 qDeleteAll(
m_d->touchShortcuts);
1113 m_d->touchShortcuts.clear();
1115 qDeleteAll(
m_d->nativeGestureShortcuts);
1116 m_d->nativeGestureShortcuts.clear();
1118 qDeleteAll(
m_d->touchpadScrollShortcuts);
1119 m_d->touchpadScrollShortcuts.clear();
1121 m_d->candidateShortcuts.clear();
1122 m_d->runningShortcut = 0;
1123 m_d->readyShortcut = 0;
1124 m_d->touchShortcut = 0;
1125 m_d->nativeGestureShortcut = 0;
1126 m_d->touchpadScrollShortcut = 0;
1131 m_d->actionGroupMask = func;
1140template<
typename T,
typename U>
1143 if (
m_d->actionsSuppressedIgnoreFocus() || (keyboard &&
m_d->KeyboardActionsSuppressed())) {
1151 if (!
m_d->suppressedSingleActionShortcuts.contains(s) &&
1153 s->
match(keysState, param) &&
1160 if (goodCandidate) {
1168 return goodCandidate;
1173 m_d->candidateShortcuts.clear();
1174 if (
m_d->actionsSuppressed())
return;
1177 bool containsOnlyModifiers = !
m_d->keys.isEmpty();
1178 Q_FOREACH(
const Qt::Key k,
m_d->keys) {
1179 if (k != Qt::Key_Shift && k != Qt::Key_Control && k != Qt::Key_Alt && k != Qt::Key_Meta) {
1180 containsOnlyModifiers =
false;
1184 if (
m_d->KeyboardActionsSuppressed()
1185 && !containsOnlyModifiers && !
m_d->keys.isEmpty()
1186 &&
m_d->buttons.isEmpty()) {
1192 m_d->candidateShortcuts.append(s);
1210 if (goodCandidate) {
1211 if (
m_d->readyShortcut) {
1212 if (
m_d->readyShortcut != goodCandidate) {
1213 if (goodCandidate->
action() ==
m_d->readyShortcut->action() &&
1216 m_d->readyShortcut = goodCandidate;
1218 m_d->readyShortcut->action()->deactivate(
m_d->readyShortcut->shortcutIndex());
1222 m_d->readyShortcut = 0;
1231 m_d->runningShortcut = goodCandidate;
1232 Private::RecursionGuard guard(
this);
1236 if (guard.brokenByRecursion()) {
1238 m_d->runningShortcut = 0;
1245 return m_d->runningShortcut;
1258 if (goodCandidate) {
1259 if (
m_d->readyShortcut &&
m_d->readyShortcut != goodCandidate) {
1260 if (goodCandidate->
action() ==
m_d->readyShortcut->action() &&
1264 m_d->readyShortcut = goodCandidate;
1267 m_d->readyShortcut->action()->deactivate(
m_d->readyShortcut->shortcutIndex());
1268 m_d->readyShortcut = 0;
1272 if (!
m_d->readyShortcut) {
1283 m_d->readyShortcut = goodCandidate;
1285 }
else if (
m_d->readyShortcut) {
1287 m_d->readyShortcut->action()->deactivate(
m_d->readyShortcut->shortcutIndex());
1288 m_d->readyShortcut = 0;
1301 if (
m_d->runningShortcut &&
m_d->runningShortcut->matchBegin(
button)) {
1305 m_d->runningShortcut = 0;
1314 QSet<Qt::MouseButton> buttonsAfterRelease =
m_d->buttons;
1315 buttonsAfterRelease.remove(
button);
1316 const bool keepReadyShortcut =
1317 !
m_d->keys.isEmpty() &&
1323 if (keepReadyShortcut) {
1331 return !
m_d->runningShortcut;
1345 m_d->runningShortcut = 0;
1348 DEBUG_ACTION(
"Forced ending running shortcut at event");
1354 action->
end(&event);
1361 if (
m_d->readyShortcut) {
1363 m_d->readyShortcut->action()->deactivate(
m_d->readyShortcut->shortcutIndex());
1364 m_d->readyShortcut = 0;
1370 int previousNumTouchPoints = -1;
1372 if (
m_d->bestCandidateForTapTouchEvent) {
1373 QTouchEvent *bestTouchEvent =
static_cast<QTouchEvent*
>(
m_d->bestCandidateForTapTouchEvent.data());
1379 if (newNumTouchPoints >= previousNumTouchPoints) {
1380#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
1381 KoPointerEvent::copyQtPointerEvent(event,
m_d->bestCandidateForTapTouchEvent);
1383 m_d->bestCandidateForTapTouchEvent.reset(event->clone());
1395 if (
m_d->actionsSuppressedIgnoreFocus())
1399 if (goodCandidate) {
1408 return goodCandidate;
1419 goodCandidate = shortcut;
1422 return goodCandidate;
1439#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1442 Q_UNREACHABLE_RETURN(
false);
1455 if (
m_d->actionsSuppressedIgnoreFocus())
1458 if (goodCandidate) {
1465 m_d->touchShortcut = goodCandidate;
1467 Private::RecursionGuard guard(
this);
1474 if (guard.brokenByRecursion()) {
1476 m_d->touchShortcut = 0;
1482 return m_d->touchShortcut;
1487 if (
m_d->touchShortcut) {
1495 m_d->touchShortcut = 0;
1503template <
typename EventType,
typename ShortcutType>
1506 ShortcutType *goodCandidate = 0;
1508 if (
m_d->actionsSuppressed())
1511 Q_FOREACH (ShortcutType* shortcut, allTypedShortcuts) {
1512 if (shortcut->match(event) && (!goodCandidate || shortcut->priority() > goodCandidate->priority())) {
1513 goodCandidate = shortcut;
1517 if (goodCandidate) {
1524 *resultShortcutPtr = goodCandidate;
1526 Private::RecursionGuard guard(
this);
1530 goodCandidate->action()->activate(goodCandidate->shortcutIndex());
1531 goodCandidate->action()->begin(goodCandidate->shortcutIndex(), event);
1534 if (guard.brokenByRecursion()) {
1535 goodCandidate->action()->end(event);
1536 *resultShortcutPtr = 0;
1542 return bool(*resultShortcutPtr);
1545template <
typename EventType,
typename ShortcutType>
1548 Private::RecursionNotifier notifier(
this);
1550 if (*resultShortcutPtr) {
1553 *resultShortcutPtr =
nullptr;
1563 if (notifier.isInRecursion()) {
1595 return m_d->touchHoldDelayMs;
1606 m_d->ignoreMultiFingerCancelWorkaround = Private::IgnoreMultiFingerCancelWorkaround();
1608 m_d->ignoreMultiFingerCancelWorkaround = std::nullopt;
1614 return m_d->ignoreMultiFingerCancelWorkaround.has_value();
float value(const T *src, size_t ch)
KisAbstractInputAction * action
virtual bool isAvailable(KisInputActionGroupsMask mask) const
bool matchTouchShortcutBasedOnState(QTouchEvent *event, KisTouchShortcut *shortcut, Qt::TouchPointStates allowedStates, TouchShortcutMode mode)
bool KeyboardActionsSuppressed() const
QSet< Qt::Key > polledKeys
void lostFocusEvent(const QPointF &localPos)
void tryActivateReadyShortcut()
bool tryEndTouchpadScrollShortcut(QWheelEvent *event)
QSet< Qt::MouseButton > buttons
QList< KisTouchpadScrollShortcut * > touchpadScrollShortcuts
KisTouchpadScrollShortcut * touchpadScrollShortcut
void forceEndRunningShortcut(const QPointF &localPos)
bool actionsSuppressedIgnoreFocus() const
bool hasRunningShortcut() const
QList< KisNativeGestureShortcut * > nativeGestureShortcuts
bool tryRunTouchpadScrollShortcut(QWheelEvent *event)
bool autoRepeatedKeyPressed(Qt::Key key)
bool buttonReleased(Qt::MouseButton button, QEvent *event)
QList< KisStrokeShortcut * > strokeShortcuts
bool touchpadScrollEndEvent(QWheelEvent *event)
bool hasTouchpadScrollShortcuts() const
std::optional< KisTouchHoldEventsPostponer > touchHoldEventPostponer
bool tryFireTapTouchShortcut(QTouchEvent *event, Qt::TouchPointStates allowedStates)
bool tryEndGestureBasedShortcutImpl(EventType *event, ShortcutType **resultShortcutPtr)
void tryCancelAllCurrentTouchActionsImpl()
void addShortcut(KisSingleActionShortcut *shortcut)
bool touchUpdateEventImpl(QTouchEvent *event)
void setTouchHoldDelay(int value)
QList< KisSingleActionShortcut * > singleActionShortcuts
bool tryRunNativeGestureShortcut(QNativeGestureEvent *event)
QList< KisStrokeShortcut * > candidateShortcuts
void toolHasBeenActivated()
bool tryRunSingleActionShortcutImpl(T param, U *event, const QSet< Qt::Key > &keysState, bool keyboard=true)
bool actionsSuppressed() const
bool nativeGestureEndEvent(QNativeGestureEvent *event)
bool tryEndTouchShortcut(QTouchEvent *event)
bool keyPressed(Qt::Key key)
bool tryRunTouchShortcut(QTouchEvent *event, Qt::TouchPointStates allowedStates, TouchShortcutMode mode)
bool touchBeginEvent(QTouchEvent *event)
void prepareReadyShortcuts()
bool suppressAllKeyboardActions
bool tryRunReadyShortcut(Qt::MouseButton button, QEvent *event)
bool touchpadScrollBeginEvent(QWheelEvent *event)
bool touchpadScrollEvent(QWheelEvent *event)
void reinitializeButtons()
KisTouchShortcut * touchShortcut
bool tryRunGestureBasedShortcutImpl(EventType *event, ShortcutType **resultShortcutPtr, const QList< ShortcutType * > allTypedShortcuts)
void setInputActionGroupsMaskCallback(std::function< KisInputActionGroupsMask()> func)
void setIgnoreMultiFingerCancelWorkaroundEnalbed(bool value)
QScopedPointer< QEvent > bestCandidateForTapTouchEvent
static constexpr qreal TOUCH_SLOP
KisStrokeShortcut * readyShortcut
void touchCancelEvent(QTouchEvent *event)
QVector< Qt::Key > debugPressedKeys() const
std::optional< IgnoreMultiFingerCancelWorkaround > ignoreMultiFingerCancelWorkaround
bool touchEndEvent(QTouchEvent *event)
bool touchUpdateEvent(QTouchEvent *event)
KisTouchShortcut * matchTouchShortcut(QTouchEvent *event, Qt::TouchPointStates allowedStates, TouchShortcutMode mode)
int touchHoldDelay() const
std::function< KisInputActionGroupsMask()> actionGroupMask
bool nativeGestureEvent(QNativeGestureEvent *event)
KisNativeGestureShortcut * nativeGestureShortcut
bool buttonPressed(Qt::MouseButton button, QEvent *event)
QList< KisTouchShortcut * > touchShortcuts
void handlePolledKeys(const QVector< Qt::Key > &keys)
bool hasTouchHoldShortcut() const
bool tryEndRunningShortcut(Qt::MouseButton button, QEvent *event)
bool tryRunWheelShortcut(KisSingleActionShortcut::WheelAction wheelAction, QWheelEvent *event)
bool sanityCheckModifiersCorrectness(Qt::KeyboardModifiers modifiers) const
bool pointerMoved(QEvent *event)
bool supportsHiResInputEvents()
bool nativeGestureBeginEvent(QNativeGestureEvent *event)
void setMaxTouchPointEvent(QTouchEvent *event)
void suppressConflictingKeyActions(const QVector< QKeySequence > &shortcuts)
KisStrokeShortcut * runningShortcut
bool keyReleased(Qt::Key key)
bool ignoreMultiFingerCancelWorkaroundEnalbed() const
QSet< KisSingleActionShortcut * > suppressedSingleActionShortcuts
void slotTouchHoldCompleted()
bool wheelEvent(KisSingleActionShortcut::WheelAction wheelAction, QWheelEvent *event)
bool tryEndNativeGestureShortcut(QNativeGestureEvent *event)
void forceDeactivateAllActions()
QScopedPointer< QTouchEvent > lastProcessedTouchEvent
bool conflictsWith(const QKeySequence &seq)
bool match(const QSet< Qt::Key > &modifiers, Qt::Key key)
int priority() const override
int priority() const override
QMouseEvent fakeEndEvent(const QPointF &localPos) const
bool matchReady(const QSet< Qt::Key > &modifiers, const QSet< Qt::MouseButton > &buttons)
bool matchBegin(Qt::MouseButton button)
@ 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...
The KisTouchShortcut class only handles touch gestures it does not handle tool invocation i....
bool isAvailable(KisInputActionGroupsMask mask) const override
static Qt::TouchPointStates pressedOnlyTouchStates()
bool matchTapType(const QTouchEvent *event, Qt::TouchPointStates allowedStates)
bool matchDragType(const QTouchEvent *event, Qt::TouchPointStates allowedStates)
static qreal touchDragDistance(const QTouchEvent *event, Qt::TouchPointStates allowedStates)
bool matchHoldType(const QTouchEvent *event, Qt::TouchPointStates allowedStates)
static int countTouchPoints(const QTouchEvent *event, Qt::TouchPointStates allowedStates)
static Qt::TouchPointStates allTouchStates()
int priority() const override
#define KIS_SAFE_ASSERT_RECOVER(cond)
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
const KRITAGLOBAL_EXPORT QLoggingCategory & _41020()
typedef void(QOPENGLF_APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer)
#define DEBUG_BUTTON_ACTION(text, button)
#define DEBUG_SHORTCUT(text, shortcut)
Qt::MouseButtons listToFlags(const QList< Qt::MouseButton > &list)
#define DEBUG_EVENT_ACTION(text, event)
QString debugShortcutName(const KisAbstractShortcut *shortcut)
#define DEBUG_TOUCH_ACTION(text, event)
QString button(const QWheelEvent &ev)
#define DEBUG_ACTION(action)
RecursionGuard(KisShortcutMatcher *_q)
bool brokenByRecursion() const
RecursionNotifier(KisShortcutMatcher *_q)
bool isInRecursion() const