[calligra] krita/ui: Add an option to disable touch capabilities of the Wacom tablets on canvas only

Dmitry Kazakov dimula73 at gmail.com
Fri May 30 10:04:33 UTC 2014


Git commit 59573e51f1736a386f78f3be3affdb2644ec25a8 by Dmitry Kazakov.
Committed on 30/05/2014 at 10:03.
Pushed by dkazakov into branch 'master'.

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/59573e51f1736a386f78f3be3affdb2644ec25a8

diff --git a/krita/ui/input/kis_input_manager.cpp b/krita/ui/input/kis_input_manager.cpp
index 94611be..56fccaa 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>
@@ -67,6 +68,8 @@ public:
         , toolProxy(0)
         , forwardAllEventsToTool(false)
         , ignoreQtCursorEvents(false)
+        , disableTouchOnCanvas(false)
+        , touchHasBlockedPressEvents(false)
     #ifdef Q_WS_X11
         , hiResEventsWorkaroundCoeff(1.0, 1.0)
     #endif
@@ -76,6 +79,8 @@ public:
         , eventsReceiver(0)
         , moveEventCompressor(10 /* ms */, KisSignalCompressor::FIRST_ACTIVE)
     {
+        KisConfig cfg;
+        disableTouchOnCanvas = cfg.disableTouchOnCanvas();
     }
 
     bool tryHidePopupPalette();
@@ -99,6 +104,9 @@ public:
     bool forwardAllEventsToTool;
     bool ignoreQtCursorEvents;
 
+    bool disableTouchOnCanvas;
+    bool touchHasBlockedPressEvents;
+
     KisShortcutMatcher matcher;
 #ifdef Q_WS_X11
     QPointF hiResEventsWorkaroundCoeff;
@@ -133,6 +141,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>();
@@ -493,6 +505,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);
 
@@ -510,6 +523,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);
@@ -598,6 +612,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);
@@ -607,6 +622,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);
@@ -632,6 +648,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
@@ -647,6 +665,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);
 
@@ -672,8 +691,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));
@@ -681,6 +709,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));
@@ -688,6 +717,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 9dee24a..1857c7a 100644
--- a/krita/ui/input/wintab/kis_tablet_support.h
+++ b/krita/ui/input/wintab/kis_tablet_support.h
@@ -88,6 +88,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 72c3344..4ea3ae2 100644
--- a/krita/ui/kis_config.cc
+++ b/krita/ui/kis_config.cc
@@ -77,6 +77,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 3eacee7..5ca4386 100644
--- a/krita/ui/kis_config.h
+++ b/krita/ui/kis_config.h
@@ -39,6 +39,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