[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