summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qapplication_x11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel/qapplication_x11.cpp')
-rw-r--r--src/gui/kernel/qapplication_x11.cpp111
1 files changed, 58 insertions, 53 deletions
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index 69dba40..0056b9e 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -4510,7 +4510,9 @@ void fetchWacomToolId(int &deviceType, qint64 &serialId)
struct qt_tablet_motion_data
{
- Time timestamp;
+ bool filterByWidget;
+ const QWidget *widget;
+ const QWidget *etWidget;
int tabletMotionType;
bool error; // found a reason to stop searching
};
@@ -4533,15 +4535,20 @@ static Bool qt_tabletMotion_scanner(Display *, XEvent *event, XPointer arg)
qt_tablet_motion_data *data = (qt_tablet_motion_data *) arg;
if (data->error)
return false;
-
if (event->type == data->tabletMotionType) {
- if (data->timestamp > 0) {
- if ((reinterpret_cast<const XDeviceMotionEvent*>(event))->time > data->timestamp) {
- data->error = true;
- return false;
+ const XDeviceMotionEvent *const motion = reinterpret_cast<const XDeviceMotionEvent*>(event);
+ if (data->filterByWidget) {
+ const QPoint curr(motion->x, motion->y);
+ const QWidget *w = data->etWidget;
+ const QWidget *const child = w->childAt(curr);
+ if (child) {
+ w = child;
}
+ if (w == data->widget)
+ return true;
+ } else {
+ return true;
}
- return true;
}
data->error = event->type != MotionNotify; // we stop compression when another event gets in between.
@@ -4574,57 +4581,17 @@ bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet
qreal rotation = 0;
int deviceType = QTabletEvent::NoDevice;
int pointerType = QTabletEvent::UnknownPointer;
- XEvent mouseMotionEvent;
- XEvent dummy;
const XDeviceMotionEvent *motion = 0;
XDeviceButtonEvent *button = 0;
const XProximityNotifyEvent *proximity = 0;
QEvent::Type t;
Qt::KeyboardModifiers modifiers = 0;
- bool reinsertMouseEvent = false;
- XEvent mouseMotionEventSave;
#if !defined (Q_OS_IRIX)
XID device_id;
#endif
if (ev->type == tablet->xinput_motion) {
motion = reinterpret_cast<const XDeviceMotionEvent*>(ev);
-
- // Do event compression. Skip over tablet+mouse move events if there are newer ones.
- qt_tablet_motion_data tabletMotionData;
- tabletMotionData.tabletMotionType = tablet->xinput_motion;
- while (true) {
- // Find first mouse event since we expect them in pairs inside Qt
- tabletMotionData.error =false;
- tabletMotionData.timestamp = 0;
- if (XCheckIfEvent(X11->display, &mouseMotionEvent, &qt_mouseMotion_scanner, (XPointer) &tabletMotionData)) {
- mouseMotionEventSave = mouseMotionEvent;
- reinsertMouseEvent = true;
- } else {
- break;
- }
-
- // Now discard any duplicate tablet events.
- tabletMotionData.error = false;
- tabletMotionData.timestamp = mouseMotionEvent.xmotion.time;
- while (XCheckIfEvent(X11->display, &dummy, &qt_tabletMotion_scanner, (XPointer) &tabletMotionData)) {
- motion = reinterpret_cast<const XDeviceMotionEvent*>(&dummy);
- }
-
- // now check if there are more recent tablet motion events since we'll compress the current one with
- // newer ones in that case
- tabletMotionData.error = false;
- tabletMotionData.timestamp = 0;
- if (! XCheckIfEvent(X11->display, &dummy, &qt_tabletMotion_scanner, (XPointer) &tabletMotionData)) {
- break; // done with compression
- }
- motion = reinterpret_cast<const XDeviceMotionEvent*>(&dummy);
- }
-
- if (reinsertMouseEvent) {
- XPutBackEvent(X11->display, &mouseMotionEventSave);
- }
-
t = QEvent::TabletMove;
global = QPoint(motion->x_root, motion->y_root);
curr = QPoint(motion->x, motion->y);
@@ -4777,11 +4744,14 @@ bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet
}
#endif
- QWidget *child = w->childAt(curr);
- if (child) {
- w = child;
- curr = w->mapFromGlobal(global);
+ if (tablet->widgetToGetPress) {
+ w = tablet->widgetToGetPress;
+ } else {
+ QWidget *child = w->childAt(curr);
+ if (child)
+ w = child;
}
+ curr = w->mapFromGlobal(global);
if (t == QEvent::TabletPress) {
tablet->widgetToGetPress = w;
@@ -4795,10 +4765,45 @@ bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet
deviceType, pointerType,
qreal(pressure / qreal(tablet->maxPressure - tablet->minPressure)),
xTilt, yTilt, tangentialPressure, rotation, z, modifiers, uid);
- if (proximity)
+ if (proximity) {
QApplication::sendSpontaneousEvent(qApp, &e);
- else
+ } else {
QApplication::sendSpontaneousEvent(w, &e);
+ const bool accepted = e.isAccepted();
+ if (!accepted && ev->type == tablet->xinput_motion) {
+ // If the widget does not accept tablet events, we drop the next ones from the event queue
+ // for this widget so it is not overloaded with the numerous tablet events.
+ qt_tablet_motion_data tabletMotionData;
+ tabletMotionData.tabletMotionType = tablet->xinput_motion;
+ tabletMotionData.widget = w;
+ tabletMotionData.etWidget = this;
+ // if nothing is pressed, the events are filtered by position
+ tabletMotionData.filterByWidget = (tablet->widgetToGetPress == 0);
+
+ bool reinsertMouseEvent = false;
+ XEvent mouseMotionEvent;
+ while (true) {
+ // Find first mouse event since we expect them in pairs inside Qt
+ tabletMotionData.error =false;
+ if (XCheckIfEvent(X11->display, &mouseMotionEvent, &qt_mouseMotion_scanner, (XPointer) &tabletMotionData)) {
+ reinsertMouseEvent = true;
+ } else {
+ break;
+ }
+
+ // Now discard any duplicate tablet events.
+ tabletMotionData.error = false;
+ XEvent dummy;
+ while (XCheckIfEvent(X11->display, &dummy, &qt_tabletMotion_scanner, (XPointer) &tabletMotionData)) {
+ // just discard the event
+ }
+ }
+
+ if (reinsertMouseEvent) {
+ XPutBackEvent(X11->display, &mouseMotionEvent);
+ }
+ }
+ }
return true;
}
#endif