Commit 59573e51 authored by Dmitry Kazakov's avatar Dmitry Kazakov
Browse files

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@kde.org
parent 2dd9a66a
......@@ -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();
......
......@@ -28,7 +28,10 @@ public:
enum ExtraEventType {
TabletMoveEx = QEvent::User,
TabletPressEx,
TabletReleaseEx
TabletReleaseEx,
TouchProximityInEx,
TouchProximityOutEx,
};
enum TabletDevice { NoDevice, Puck, Stylus, Airbrush, FourDMouse,
......
......@@ -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
......
......@@ -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;
}
}
}
}
......
......@@ -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);
......
......@@ -39,6 +39,9 @@ public:
KisConfig();
~KisConfig();
bool disableTouchOnCanvas() const;
void setDisableTouchOnCanvas(bool value) const;
bool useProjections() const;
void setUseProjections(bool useProj) const;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment