10#include <QApplication>
11#include <QScopedPointer>
14#include <boost/preprocessor/repeat_from_to.hpp>
28#include "config-qt-patches-present.h"
62 return (t == QEvent::MouseMove ||
63 t == QEvent::MouseButtonPress ||
64 t == QEvent::MouseButtonRelease ||
65 t == QEvent::MouseButtonDblClick);
80 QString pre = QString(
"[BLOCKED %1:]").arg(i);
81 QMouseEvent *ev =
static_cast<QMouseEvent*
>(event);
86 auto debugTabletEvent = [&](
int i) {
88 QString pre = QString(
"[BLOCKED %1:]").arg(i);
89 QTabletEvent *ev =
static_cast<QTabletEvent*
>(event);
94 auto debugTouchEvent = [&](
int i) {
96 QString pre = QString(
"[BLOCKED %1:]").arg(i);
97 QTouchEvent *ev =
static_cast<QTouchEvent*
>(event);
102 if (peckish && event->type() == QEvent::MouseButtonPress
104 && (
static_cast<QMouseEvent*
>(event)->button() == Qt::LeftButton)) {
110 if (activateSecondaryButtonsWorkaround) {
111 if (event->type() == QEvent::TabletPress ||
112 event->type() == QEvent::TabletRelease) {
114 QTabletEvent *te =
static_cast<QTabletEvent*
>(event);
115 if (te->button() != Qt::LeftButton) {
119 }
else if (event->type() == QEvent::MouseButtonPress ||
120 event->type() == QEvent::MouseButtonRelease ||
121 event->type() == QEvent::MouseButtonDblClick) {
123 QMouseEvent *me =
static_cast<QMouseEvent*
>(event);
124 if (me->button() != Qt::LeftButton) {
135 || (eatSyntheticEvents &&
static_cast<QMouseEvent*
>(event)->
source() != Qt::MouseEventNotSynthesized)
143 if (eatTouchEvents && event->type() == QEvent::TouchBegin) {
158 dbgTablet <<
"Start blocking mouse events";
166 dbgTablet <<
"Stop blocking mouse events";
179 eatTouchEvents =
true;
184 eatTouchEvents =
false;
234#if defined Q_OS_LINUX && !KRITA_QT_HAS_UNBALANCED_KEY_PRESS_RELEASE_PATCH
238 if (qEnvironmentVariableIsSet(
"KRITA_FIX_UNBALANCED_KEY_EVENTS")) {
249 eatOneMouseStroke(false),
256 QWidget *widget = qobject_cast<QWidget*>(
object);
259 thresholdConnections.clear();
260 thresholdConnections.addConnection(&focusSwitchThreshold, SIGNAL(timeout()), widget, SLOT(setFocus()));
267 QObject *canvasWidget =
canvas->canvasWidget();
269 if (!canvasResolver.contains(canvasWidget)) {
270 canvasResolver.insert(canvasWidget,
canvas);
279 canvasWidget->installEventFilter(
this);
281 setupFocusThreshold(canvasWidget);
282 focusSwitchThreshold.setEnabled(
false);
291 QObject *widget =
canvas->canvasWidget();
293 canvasResolver.remove(widget);
299 widget->removeEventFilter(
this);
309 if (!w)
return false;
313 types << QLatin1String(
"QAbstractSlider");
314 types << QLatin1String(
"QAbstractSpinBox");
315 types << QLatin1String(
"QLineEdit");
316 types << QLatin1String(
"QTextEdit");
317 types << QLatin1String(
"QPlainTextEdit");
318 types << QLatin1String(
"QComboBox");
319 types << QLatin1String(
"QKeySequenceEdit");
321 Q_FOREACH (
const QLatin1String &type, types) {
322 if (w->inherits(type.data())) {
332 if (canvasResolver.contains(
object)) {
333 switch (event->type()) {
334 case QEvent::FocusIn: {
335 QFocusEvent *fevent =
static_cast<QFocusEvent*
>(event);
343 eatOneMouseStroke = 2 * (fevent->reason() == Qt::MouseFocusReason);
351 object->removeEventFilter(
this);
352 object->installEventFilter(
this);
354 setupFocusThreshold(
object);
355 focusSwitchThreshold.setEnabled(
false);
357 const QPoint globalPos = QCursor::pos();
358 const QPoint localPos =
d->
canvas->canvasWidget()->mapFromGlobal(globalPos);
359 QWidget *canvasWindow =
d->
canvas->canvasWidget()->window();
360 const QPoint windowsPos = canvasWindow ? canvasWindow->mapFromGlobal(globalPos) : localPos;
362 QEnterEvent event(localPos, windowsPos, globalPos);
366 case QEvent::FocusOut: {
367 focusSwitchThreshold.setEnabled(
true);
370 case QEvent::Enter: {
373 case QEvent::Leave: {
374 focusSwitchThreshold.stop();
377 case QEvent::Wheel: {
378 QWidget *widget =
static_cast<QWidget*
>(object);
382 case QEvent::MouseButtonPress:
383 case QEvent::MouseButtonRelease:
384 case QEvent::TabletPress:
385 case QEvent::TabletRelease:
386 focusSwitchThreshold.forceDone();
388 if (eatOneMouseStroke) {
393 case QEvent::MouseButtonDblClick:
394 focusSwitchThreshold.forceDone();
395 if (eatOneMouseStroke) {
399 case QEvent::MouseMove:
400 case QEvent::TabletMove: {
401 QWidget *widget =
static_cast<QWidget*
>(object);
403 if (!widget->hasFocus()) {
408 focusSwitchThreshold.setDelayThreshold(delay);
409 focusSwitchThreshold.start();
417 return QObject::eventFilter(
object, event);
426 switch (event->type()) {
427 case QEvent::TabletEnterProximity:
440 case QEvent::TabletLeaveProximity:
445 case QEvent::KeyPress:
446 case QEvent::KeyRelease:
447 case QEvent::ShortcutOverride:
448 if (
d->ignoreHighFunctionKeys) {
449 QKeyEvent *keyEvent =
static_cast<QKeyEvent *
>(event);
450 int key = keyEvent->key();
452 if (key >= Qt::Key_F13 && key <= Qt::Key_F35) {
454 const QString pre =
"[BLOCKED HIGH F-KEY]";
465 return QObject::eventFilter(
object, event);
468#define EXTRA_BUTTON(z, n, _) \
469 if(buttons & Qt::ExtraButton##n) { \
470 buttonSet << Qt::ExtraButton##n; \
480 QSet<Qt::MouseButton> buttonSet;
482 buttonSet << Qt::LeftButton;
484 if(
buttons & Qt::RightButton) {
485 buttonSet << Qt::RightButton;
487 if(
buttons & Qt::MiddleButton) {
488 buttonSet << Qt::MiddleButton;
493 if (!buttonSet.empty()) {
494 strokeShortcut->
setButtons(QSet<Qt::Key>(modifiers.cbegin(), modifiers.cend()), buttonSet);
498 delete strokeShortcut;
505 if (keys.size() == 0)
return;
515 Qt::Key key = allKeys.takeLast();
516 QSet<Qt::Key> modifiers = QSet<Qt::Key>(allKeys.begin(), allKeys.end());
517 keyShortcut->
setKey(modifiers, key);
525 QScopedPointer<KisSingleActionShortcut> keyShortcut(
529 switch(wheelAction) {
548 keyShortcut->setWheel(QSet<Qt::Key>(modifiers.begin(), modifiers.end()), a);
595 Qt::NativeGestureType type;
598 case KisShortcutConfiguration::PinchGesture:
599 type = Qt::ZoomNativeGesture;
601 case KisShortcutConfiguration::PanGesture:
602 type = Qt::PanNativeGesture;
604 case KisShortcutConfiguration::RotateGesture:
605 type = Qt::RotateNativeGesture;
607 case KisShortcutConfiguration::SmartZoomGesture:
608 type = Qt::SmartZoomNativeGesture;
643 event->type() == QEvent::KeyPress ||
644 event->type() == QEvent::KeyRelease) {
654inline QPointF dividePoints(
const QPointF &pt1,
const QPointF &pt2) {
655 return QPointF(pt1.x() / pt2.x(), pt1.y() / pt2.y());
658inline QPointF multiplyPoints(
const QPointF &pt1,
const QPointF &pt2) {
659 return QPointF(pt1.x() * pt2.x(), pt1.y() * pt2.y());
724 event->setAccepted(
true);
736 QKeyEvent kevent(QEvent::ShortcutOverride, key, modifiers);
749 for (
auto it = danglingKeys.begin(); it != danglingKeys.end();) {
750 if (newKeys.contains(*it)) {
751 newKeys.removeOne(*it);
752 it = danglingKeys.erase(it);
758 Q_FOREACH (Qt::Key key, danglingKeys) {
759 QKeyEvent kevent(QEvent::KeyRelease, key, modifiers);
763 Q_FOREACH (Qt::Key key, newKeys) {
766 QKeyEvent kevent(QEvent::ShortcutOverride, key, modifiers);
770 QKeyEvent kevent(QEvent::KeyPress, key, modifiers);
782 QElapsedTimer elapsed;
784 return elapsed.msecsSinceReference();
float value(const T *src, size_t ch)
KisMagneticGraph::vertex_descriptor target(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
static bool debugEnabled()
Linethickness.
bool testingAcceptCompressedTabletEvents(bool defaultValue=false) const
int tabletEventsDelay(bool defaultValue=false) const
bool trackTabletEventLatency(bool defaultValue=false) const
bool useRightMiddleTabletButtonWorkaround(bool defaultValue=false) const
bool testingCompressBrushEvents(bool defaultValue=false) const
static Qt::Key workaroundShiftAltMetaHell(const QKeyEvent *keyEvent)
Qt::KeyboardModifiers queryStandardModifiers()
ExtendedModifiers queryExtendedModifiers()
@ WheelTrackpad
A pan movement on a trackpad.
@ WheelDown
Downwards movement, toward the user.
@ WheelUp
Upwards movement, away from the user.
@ WheelLeft
Left movement.
@ WheelRight
Right movement.
bool hasRunningShortcut() const
void addShortcut(KisSingleActionShortcut *shortcut)
void setInputActionGroupsMaskCallback(std::function< KisInputActionGroupsMask()> func)
QVector< Qt::Key > debugPressedKeys() const
bool touchUpdateEvent(QTouchEvent *event)
void handlePolledKeys(const QVector< Qt::Key > &keys)
bool pointerMoved(QEvent *event)
void setDelay(std::function< bool()> idleCallback, int idleDelay, int timeout)
@ WheelDown
Mouse wheel moves down.
@ WheelTrackpad
A pan movement on a trackpad.
@ WheelUp
Mouse wheel moves up.
@ WheelRight
Mouse wheel moves right.
@ WheelLeft
Mouse wheel moves left.
void setKey(const QSet< Qt::Key > &modifiers, Qt::Key key)
void setButtons(const QSet< Qt::Key > &modifiers, const QSet< Qt::MouseButton > &buttons)
QString eventToString(const QMouseEvent &ev, const QString &prefix)
static KisTabletDebugger * instance()
bool debugEnabled() const
The KisTouchShortcut class only handles touch gestures it does not handle tool invocation i....
void setMaximumTouchPoints(int max)
void setDisableOnTouchPainting(bool disableOnTouchPainting)
void setMinimumTouchPoints(int min)
#define KIS_SAFE_ASSERT_RECOVER_BREAK(cond)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
QString buttons(const T &ev)