diff options
Diffstat (limited to 'src/gui/kernel/qapplication_x11.cpp')
-rw-r--r-- | src/gui/kernel/qapplication_x11.cpp | 111 |
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 |