[calligra/calligra/2.8] krita/ui: Add an option to disable touch capabilities of the Wacom tablets on canvas only
Dmitry Kazakov
dimula73 at gmail.com
Sat Aug 23 14:54:00 UTC 2014
Git commit f7cc48181bf6db059153820e034b7e18cfde48a7 by Dmitry Kazakov.
Committed on 30/05/2014 at 10:03.
Pushed by dkazakov into branch 'calligra/2.8'.
Add an option to disable touch capabilities of the Wacom tablets on canvas only
If you want to use it, please add the following option to your kritarc file
disableTouchOnCanvas=true
(tested on linux only)
BUG:332773
CCMAIL:kimageshop at kde.org
M +30 -0 krita/ui/input/kis_input_manager.cpp
M +4 -1 krita/ui/input/kis_tablet_event.h
M +2 -0 krita/ui/input/wintab/kis_tablet_support.h
M +70 -0 krita/ui/input/wintab/kis_tablet_support_x11.cpp
M +10 -0 krita/ui/kis_config.cc
M +3 -0 krita/ui/kis_config.h
http://commits.kde.org/calligra/f7cc48181bf6db059153820e034b7e18cfde48a7
diff --git a/krita/ui/input/kis_input_manager.cpp b/krita/ui/input/kis_input_manager.cpp
index 9bcebcf..fa5aeb9 100644
--- a/krita/ui/input/kis_input_manager.cpp
+++ b/krita/ui/input/kis_input_manager.cpp
@@ -28,6 +28,7 @@
#include "kis_tool_proxy.h"
+#include <kis_config.h>
#include <kis_canvas2.h>
#include <kis_view2.h>
#include <kis_image.h>
@@ -68,6 +69,8 @@ public:
, setMirrorMode(false)
, forwardAllEventsToTool(false)
, ignoreQtCursorEvents(false)
+ , disableTouchOnCanvas(false)
+ , touchHasBlockedPressEvents(false)
#ifdef Q_WS_X11
, hiResEventsWorkaroundCoeff(1.0, 1.0)
#endif
@@ -77,6 +80,8 @@ public:
, eventsReceiver(0)
, moveEventCompressor(10 /* ms */, KisSignalCompressor::FIRST_ACTIVE)
{
+ KisConfig cfg;
+ disableTouchOnCanvas = cfg.disableTouchOnCanvas();
}
bool tryHidePopupPalette();
@@ -102,6 +107,9 @@ public:
bool forwardAllEventsToTool;
bool ignoreQtCursorEvents;
+ bool disableTouchOnCanvas;
+ bool touchHasBlockedPressEvents;
+
KisShortcutMatcher matcher;
#ifdef Q_WS_X11
QPointF hiResEventsWorkaroundCoeff;
@@ -136,6 +144,10 @@ void KisInputManager::Private::debugEvent(QEvent *event)
#define stop_ignore_cursor_events() d->ignoreQtCursorEvents = false
#define break_if_should_ignore_cursor_events() if (d->ignoreQtCursorEvents) break;
+#define touch_start_block_press_events() d->touchHasBlockedPressEvents = d->disableTouchOnCanvas
+#define touch_stop_block_press_events() d->touchHasBlockedPressEvents = false
+#define break_if_touch_blocked_press_events() if (d->touchHasBlockedPressEvents) break;
+
static inline QList<Qt::Key> KEYS() {
return QList<Qt::Key>();
@@ -514,6 +526,7 @@ bool KisInputManager::eventFilter(QObject* object, QEvent* event)
case QEvent::MouseButtonDblClick: {
d->debugEvent<QMouseEvent, true>(event);
break_if_should_ignore_cursor_events();
+ break_if_touch_blocked_press_events();
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
@@ -531,6 +544,7 @@ bool KisInputManager::eventFilter(QObject* object, QEvent* event)
case QEvent::MouseButtonRelease: {
d->debugEvent<QMouseEvent, true>(event);
break_if_should_ignore_cursor_events();
+ break_if_touch_blocked_press_events();
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
retval = d->matcher.buttonReleased(mouseEvent->button(), mouseEvent);
@@ -619,6 +633,7 @@ bool KisInputManager::eventFilter(QObject* object, QEvent* event)
//Ensure we have focus so we get key events.
d->canvas->canvasWidget()->setFocus();
stop_ignore_cursor_events();
+ touch_stop_block_press_events();
break;
case QEvent::Leave:
d->debugEvent<QEvent, false>(event);
@@ -628,6 +643,7 @@ bool KisInputManager::eventFilter(QObject* object, QEvent* event)
* events processing right now.
*/
stop_ignore_cursor_events();
+ touch_stop_block_press_events();
break;
case QEvent::FocusIn:
d->debugEvent<QEvent, false>(event);
@@ -653,6 +669,8 @@ bool KisInputManager::eventFilter(QObject* object, QEvent* event)
case QEvent::TabletRelease: {
d->debugEvent<QTabletEvent, true>(event);
break_if_should_ignore_cursor_events();
+ break_if_touch_blocked_press_events();
+
//We want both the tablet information and the mouse button state.
//Since QTabletEvent only provides the tablet information, we
//save that and then ignore the event so it will generate a mouse
@@ -668,6 +686,7 @@ bool KisInputManager::eventFilter(QObject* object, QEvent* event)
case KisTabletEvent::TabletReleaseEx: {
d->debugEvent<KisTabletEvent, false>(event);
stop_ignore_cursor_events();
+ touch_stop_block_press_events();
KisTabletEvent *tevent = static_cast<KisTabletEvent*>(event);
@@ -693,8 +712,17 @@ bool KisInputManager::eventFilter(QObject* object, QEvent* event)
break;
}
+ case KisTabletEvent::TouchProximityInEx: {
+ touch_start_block_press_events();
+ break;
+ }
+ case KisTabletEvent::TouchProximityOutEx: {
+ touch_stop_block_press_events();
+ break;
+ }
case QEvent::TouchBegin:
+ touch_start_block_press_events();
KisAbstractInputAction::setInputManager(this);
retval = d->matcher.touchBeginEvent(static_cast<QTouchEvent*>(event));
@@ -702,6 +730,7 @@ bool KisInputManager::eventFilter(QObject* object, QEvent* event)
d->resetSavedTabletEvent(event->type());
break;
case QEvent::TouchUpdate:
+ touch_start_block_press_events();
KisAbstractInputAction::setInputManager(this);
retval = d->matcher.touchUpdateEvent(static_cast<QTouchEvent*>(event));
@@ -709,6 +738,7 @@ bool KisInputManager::eventFilter(QObject* object, QEvent* event)
d->resetSavedTabletEvent(event->type());
break;
case QEvent::TouchEnd:
+ touch_stop_block_press_events();
d->saveTouchEvent(static_cast<QTouchEvent*>(event));
retval = d->matcher.touchEndEvent(static_cast<QTouchEvent*>(event));
event->accept();
diff --git a/krita/ui/input/kis_tablet_event.h b/krita/ui/input/kis_tablet_event.h
index 744f4ff..0b3d15d 100644
--- a/krita/ui/input/kis_tablet_event.h
+++ b/krita/ui/input/kis_tablet_event.h
@@ -28,7 +28,10 @@ public:
enum ExtraEventType {
TabletMoveEx = QEvent::User,
TabletPressEx,
- TabletReleaseEx
+ TabletReleaseEx,
+
+ TouchProximityInEx,
+ TouchProximityOutEx,
};
enum TabletDevice { NoDevice, Puck, Stylus, Airbrush, FourDMouse,
diff --git a/krita/ui/input/wintab/kis_tablet_support.h b/krita/ui/input/wintab/kis_tablet_support.h
index e12ce40..4ef69d1 100644
--- a/krita/ui/input/wintab/kis_tablet_support.h
+++ b/krita/ui/input/wintab/kis_tablet_support.h
@@ -86,6 +86,8 @@ struct QTabletDeviceData
#endif
#ifdef Q_WS_X11
+ bool isTouchWacomTablet;
+
/**
* Different tablets have different assignment of axes reported by
* the XInput subsystem. More than that some of the drivers demand
diff --git a/krita/ui/input/wintab/kis_tablet_support_x11.cpp b/krita/ui/input/wintab/kis_tablet_support_x11.cpp
index 186526c..3670380 100644
--- a/krita/ui/input/wintab/kis_tablet_support_x11.cpp
+++ b/krita/ui/input/wintab/kis_tablet_support_x11.cpp
@@ -24,6 +24,7 @@
#include <QX11Info>
#include "kis_debug.h"
+#include "kis_config.h"
#include <input/kis_tablet_event.h>
#include "kis_tablet_support.h"
#include "wacomcfg.h"
@@ -109,6 +110,8 @@ struct KisX11Data
AbsTiltX,
AbsTiltY,
+ WacomTouch,
+
NPredefinedAtoms,
NAtoms = NPredefinedAtoms
};
@@ -143,6 +146,9 @@ static const char * kis_x11_atomnames = {
"Abs Tilt X\0"
"Abs Tilt Y\0"
+ // Touch capabilities reported by Wacom Intuos tablets
+ "TOUCH\0"
+
};
KisX11Data *kis_x11Data = 0;
@@ -232,6 +238,9 @@ void QTabletDeviceData::SavedAxesData::tryFetchAxesMapping(XDevice *dev)
void kis_x11_init_tablet()
{
+ KisConfig cfg;
+ bool disableTouchOnCanvas = cfg.disableTouchOnCanvas();
+
// TODO: free this structure on exit
KIS_X11 = new KisX11Data;
KIS_X11->display = QX11Info::display();
@@ -274,6 +283,7 @@ void kis_x11_init_tablet()
XDevice *dev = 0;
bool needCheckIfItIsReallyATablet;
+ bool touchWacomTabletWorkaround;
if (KIS_X11->ptrXListInputDevices) {
devices = KIS_X11->ptrXListInputDevices(KIS_X11->display, &ndev);
@@ -290,6 +300,7 @@ void kis_x11_init_tablet()
gotStylus = false;
gotEraser = false;
needCheckIfItIsReallyATablet = false;
+ touchWacomTabletWorkaround = false;
#if defined(Q_OS_IRIX)
#else
@@ -319,6 +330,14 @@ void kis_x11_init_tablet()
deviceType = QTabletEvent::Stylus;
gotStylus = true;
needCheckIfItIsReallyATablet = true;
+ } else if (disableTouchOnCanvas &&
+ devs->type == KIS_ATOM(WacomTouch) &&
+ QString(devs->name).contains("Wacom")) {
+
+ kis_haveEvdevTablets = true;
+ deviceType = QTabletEvent::Stylus;
+ gotStylus = true;
+ touchWacomTabletWorkaround = true;
}
#endif
@@ -343,6 +362,7 @@ void kis_x11_init_tablet()
device_data.xinput_button_release = -1;
device_data.xinput_proximity_in = -1;
device_data.xinput_proximity_out = -1;
+ device_data.isTouchWacomTablet = touchWacomTabletWorkaround;
//device_data.widgetToGetPress = 0;
if (dev->num_classes > 0) {
@@ -620,6 +640,12 @@ bool translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet, QWidget *
}
}
+ /**
+ * Touch events from Wacom tablets should not be sent as real
+ * tablet events
+ */
+ if (tablet->isTouchWacomTablet) return false;
+
fetchWacomToolId(deviceType, uid);
QRect screenArea = qApp->desktop()->rect();
@@ -775,6 +801,50 @@ bool KisTabletSupportX11::eventFilter(void *ev, long * /*unused_on_X11*/)
}
return retval;
+ } else if (event->type == tab.xinput_proximity_in ||
+ event->type == tab.xinput_proximity_out) {
+
+ const XProximityNotifyEvent *proximity =
+ reinterpret_cast<const XProximityNotifyEvent*>(event);
+ XID device_id = proximity->deviceid;
+
+ QTabletDeviceDataList *tablet_list = qt_tablet_devices();
+ for (int i = 0; i < tablet_list->size(); ++i) {
+ QTabletDeviceData &tab = tablet_list->operator[](i);
+ if (device_id == static_cast<XDevice *>(tab.device)->device_id &&
+ tab.isTouchWacomTablet) {
+
+ QWidget *widget = QApplication::activePopupWidget();
+
+ if (!widget) {
+ widget = QApplication::activeModalWidget();
+ }
+
+ if (!widget) {
+ widget = QWidget::find((WId)event->xany.window);
+ }
+
+ if (widget) {
+ QPoint curr(proximity->x, proximity->y);
+ QWidget *child = widget->childAt(curr);
+
+ if (child) {
+ widget = child;
+ }
+
+ QEvent::Type type = (QEvent::Type)
+ (event->type == tab.xinput_proximity_in ?
+ KisTabletEvent::TouchProximityInEx :
+ KisTabletEvent::TouchProximityOutEx);
+
+ QEvent e(type);
+ e.ignore();
+ QApplication::sendEvent(widget, &e);
+ }
+
+ return true;
+ }
+ }
}
}
diff --git a/krita/ui/kis_config.cc b/krita/ui/kis_config.cc
index 06f4d1b..f79397f 100644
--- a/krita/ui/kis_config.cc
+++ b/krita/ui/kis_config.cc
@@ -76,6 +76,16 @@ KisConfig::~KisConfig()
}
+bool KisConfig::disableTouchOnCanvas() const
+{
+ return m_cfg.readEntry("disableTouchOnCanvas", false);
+}
+
+void KisConfig::setDisableTouchOnCanvas(bool value) const
+{
+ m_cfg.writeEntry("disableTouchOnCanvas", value);
+}
+
bool KisConfig::useProjections() const
{
return m_cfg.readEntry("useProjections", true);
diff --git a/krita/ui/kis_config.h b/krita/ui/kis_config.h
index d0cac9d..b5efcf1 100644
--- a/krita/ui/kis_config.h
+++ b/krita/ui/kis_config.h
@@ -38,6 +38,9 @@ public:
KisConfig();
~KisConfig();
+ bool disableTouchOnCanvas() const;
+ void setDisableTouchOnCanvas(bool value) const;
+
bool useProjections() const;
void setUseProjections(bool useProj) const;
More information about the kimageshop
mailing list