Fix QMouse/Wheel/TouchEvent::modifiers with the XCB back-end
authorSimon Hausmann <simon.hausmann@nokia.com>
Fri, 7 Oct 2011 12:54:17 +0000 (14:54 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 7 Oct 2011 16:27:53 +0000 (18:27 +0200)
The modifiers are provided by X and need to be propagated through the
QWindowSystemInterface.

Change-Id: I127d0b6e9918b558ca15d9302c4cc0cbd94eb757
Reviewed-on: http://codereview.qt-project.org/6244
Reviewed-by: Laszlo Agocs <laszlo.p.agocs@nokia.com>
Sanity-Review: Samuel Rødal <samuel.rodal@nokia.com>
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
Sanity-Review: Qt Sanity Bot <qt_sanity_bot@ovi.com>

src/gui/kernel/qguiapplication.cpp
src/gui/kernel/qwindowsysteminterface_qpa.cpp
src/gui/kernel/qwindowsysteminterface_qpa.h
src/gui/kernel/qwindowsysteminterface_qpa_p.h
src/plugins/platforms/xcb/qxcbwindow.cpp
src/plugins/platforms/xcb/qxcbwindow.h

index 22443ee..29b961a 100644 (file)
@@ -567,7 +567,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
     Qt::MouseButtons stateChange = e->buttons ^ buttons;
     if (e->globalPos != QGuiApplicationPrivate::lastCursorPosition && (stateChange != Qt::NoButton)) {
         QWindowSystemInterfacePrivate::MouseEvent * newMouseEvent =
-                new QWindowSystemInterfacePrivate::MouseEvent(e->window.data(), e->timestamp, e->localPos, e->globalPos, e->buttons);
+                new QWindowSystemInterfacePrivate::MouseEvent(e->window.data(), e->timestamp, e->localPos, e->globalPos, e->buttons, e->modifiers);
         QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(newMouseEvent); // just in case the move triggers a new event loop
         stateChange = Qt::NoButton;
     }
@@ -624,7 +624,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
 
 
     if (window) {
-        QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, QGuiApplication::keyboardModifiers());
+        QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers);
         ev.setTimestamp(e->timestamp);
 #ifndef QT_NO_CURSOR
         QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances();
@@ -651,7 +651,7 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh
     QWindow *window = e->window.data();
 
     if (window) {
-         QWheelEvent ev(e->localPos, e->globalPos, e->delta, buttons, QGuiApplication::keyboardModifiers(),
+         QWheelEvent ev(e->localPos, e->globalPos, e->delta, buttons, e->modifiers,
                         e->orient);
          ev.setTimestamp(e->timestamp);
          QGuiApplication::sendSpontaneousEvent(window, &ev);
@@ -894,7 +894,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
 
         QTouchEvent touchEvent(eventType,
                                e->devType,
-                               QGuiApplication::keyboardModifiers(),
+                               e->modifiers,
                                it.value().first,
                                it.value().second);
         touchEvent.setTimestamp(e->timestamp);
index bad1b86..1745c1b 100644 (file)
@@ -114,15 +114,15 @@ void QWindowSystemInterface::handleCloseEvent(QWindow *tlw)
 
 
 */
-void QWindowSystemInterface::handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b) {
+void QWindowSystemInterface::handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) {
     unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
-    handleMouseEvent(w, time, local, global, b);
+    handleMouseEvent(w, time, local, global, b, mods);
 }
 
-void QWindowSystemInterface::handleMouseEvent(QWindow *tlw, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b)
+void QWindowSystemInterface::handleMouseEvent(QWindow *tlw, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
 {
     QWindowSystemInterfacePrivate::MouseEvent * e =
-            new QWindowSystemInterfacePrivate::MouseEvent(tlw, timestamp, local, global, b);
+            new QWindowSystemInterfacePrivate::MouseEvent(tlw, timestamp, local, global, b, mods);
     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
 }
 
@@ -162,15 +162,15 @@ void QWindowSystemInterface::handleExtendedKeyEvent(QWindow *tlw, ulong timestam
     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
 }
 
-void QWindowSystemInterface::handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, int d, Qt::Orientation o) {
+void QWindowSystemInterface::handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, int d, Qt::Orientation o, Qt::KeyboardModifiers mods) {
     unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
-    handleWheelEvent(w, time, local, global, d, o);
+    handleWheelEvent(w, time, local, global, d, o, mods);
 }
 
-void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, const QPointF & local, const QPointF & global, int d, Qt::Orientation o)
+void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, const QPointF & local, const QPointF & global, int d, Qt::Orientation o, Qt::KeyboardModifiers mods)
 {
     QWindowSystemInterfacePrivate::WheelEvent *e =
-            new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, d, o);
+            new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, d, o, mods);
     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
 }
 
@@ -205,12 +205,12 @@ void QWindowSystemInterfacePrivate::queueWindowSystemEvent(QWindowSystemInterfac
         dispatcher->wakeUp();
 }
 
-void QWindowSystemInterface::handleTouchEvent(QWindow *w, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points) {
+void QWindowSystemInterface::handleTouchEvent(QWindow *w, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points, Qt::KeyboardModifiers mods) {
     unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
-    handleTouchEvent(w, time, type, devType, points);
+    handleTouchEvent(w, time, type, devType, points, mods);
 }
 
-void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points)
+void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points, Qt::KeyboardModifiers mods)
 {
     if (!points.size()) // Touch events must have at least one point
         return;
@@ -245,7 +245,7 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QEv
     }
 
     QWindowSystemInterfacePrivate::TouchEvent *e =
-            new QWindowSystemInterfacePrivate::TouchEvent(tlw, timestamp, type, devType, touchPoints);
+            new QWindowSystemInterfacePrivate::TouchEvent(tlw, timestamp, type, devType, touchPoints, mods);
     QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
 }
 
index 99db5f2..0581899 100644 (file)
@@ -62,8 +62,8 @@ QT_MODULE(Gui)
 class Q_GUI_EXPORT QWindowSystemInterface
 {
 public:
-    static void handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b);
-    static void handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b);
+    static void handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier);
+    static void handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier);
 
     static void handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
     static void handleKeyEvent(QWindow *w, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
@@ -79,8 +79,8 @@ public:
                                        const QString& text = QString(), bool autorep = false,
                                        ushort count = 1);
 
-    static void handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, int d, Qt::Orientation o);
-    static void handleWheelEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, int d, Qt::Orientation o);
+    static void handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, int d, Qt::Orientation o, Qt::KeyboardModifiers mods = Qt::NoModifier);
+    static void handleWheelEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, int d, Qt::Orientation o, Qt::KeyboardModifiers mods = Qt::NoModifier);
 
     struct TouchPoint {
         int id;                 // for application use
@@ -91,8 +91,8 @@ public:
         Qt::TouchPointState state; //Qt::TouchPoint{Pressed|Moved|Stationary|Released}
     };
 
-    static void handleTouchEvent(QWindow *w, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points);
-    static void handleTouchEvent(QWindow *w, ulong timestamp, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points);
+    static void handleTouchEvent(QWindow *w, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points, Qt::KeyboardModifiers mods = Qt::NoModifier);
+    static void handleTouchEvent(QWindow *w, ulong timestamp, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points, Qt::KeyboardModifiers mods = Qt::NoModifier);
 
     static void handleGeometryChange(QWindow *w, const QRect &newRect);
     static void handleSynchronousGeometryChange(QWindow *w, const QRect &newRect);
index 77c2197..121c997 100644 (file)
@@ -134,52 +134,60 @@ public:
         unsigned long timestamp;
     };
 
-    class MouseEvent : public UserEvent {
+    class InputEvent: public UserEvent {
     public:
-        MouseEvent(QWindow * w, ulong time, const QPointF & local, const QPointF & global, Qt::MouseButtons b)
-            : UserEvent(w, time, Mouse), localPos(local), globalPos(global), buttons(b) { }
+        InputEvent(QWindow * w, ulong time, EventType t, Qt::KeyboardModifiers mods)
+            : UserEvent(w, time, t), modifiers(mods) {}
+        Qt::KeyboardModifiers modifiers;
+    };
+
+    class MouseEvent : public InputEvent {
+    public:
+        MouseEvent(QWindow * w, ulong time, const QPointF & local, const QPointF & global,
+                   Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+            : InputEvent(w, time, Mouse, mods), localPos(local), globalPos(global), buttons(b) { }
         QPointF localPos;
         QPointF globalPos;
         Qt::MouseButtons buttons;
     };
 
-    class WheelEvent : public UserEvent {
+    class WheelEvent : public InputEvent {
     public:
-        WheelEvent(QWindow *w, ulong time, const QPointF & local, const QPointF & global, int d, Qt::Orientation o)
-            : UserEvent(w, time, Wheel), delta(d), localPos(local), globalPos(global), orient(o) { }
+        WheelEvent(QWindow *w, ulong time, const QPointF & local, const QPointF & global, int d,
+                   Qt::Orientation o, Qt::KeyboardModifiers mods)
+            : InputEvent(w, time, Wheel, mods), delta(d), localPos(local), globalPos(global), orient(o) { }
         int delta;
         QPointF localPos;
         QPointF globalPos;
         Qt::Orientation orient;
     };
 
-    class KeyEvent : public UserEvent {
+    class KeyEvent : public InputEvent {
     public:
         KeyEvent(QWindow *w, ulong time, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1)
-            :UserEvent(w, time, Key), key(k), unicode(text), repeat(autorep),
-             repeatCount(count), modifiers(mods), keyType(t),
+            :InputEvent(w, time, Key, mods), key(k), unicode(text), repeat(autorep),
+             repeatCount(count), keyType(t),
              nativeScanCode(0), nativeVirtualKey(0), nativeModifiers(0) { }
         KeyEvent(QWindow *w, ulong time, QEvent::Type t, int k, Qt::KeyboardModifiers mods,
                  quint32 nativeSC, quint32 nativeVK, quint32 nativeMods,
                  const QString & text = QString(), bool autorep = false, ushort count = 1)
-            :UserEvent(w, time, Key), key(k), unicode(text), repeat(autorep),
-             repeatCount(count), modifiers(mods), keyType(t),
+            :InputEvent(w, time, Key, mods), key(k), unicode(text), repeat(autorep),
+             repeatCount(count), keyType(t),
              nativeScanCode(nativeSC), nativeVirtualKey(nativeVK), nativeModifiers(nativeMods) { }
         int key;
         QString unicode;
         bool repeat;
         ushort repeatCount;
-        Qt::KeyboardModifiers modifiers;
         QEvent::Type keyType;
         quint32 nativeScanCode;
         quint32 nativeVirtualKey;
         quint32 nativeModifiers;
     };
 
-    class TouchEvent : public UserEvent {
+    class TouchEvent : public InputEvent {
     public:
-        TouchEvent(QWindow *w, ulong time, QEvent::Type t, QTouchEvent::DeviceType d, const QList<QTouchEvent::TouchPoint> &p)
-            :UserEvent(w, time, Touch), devType(d), points(p), touchType(t) { }
+        TouchEvent(QWindow *w, ulong time, QEvent::Type t, QTouchEvent::DeviceType d, const QList<QTouchEvent::TouchPoint> &p, Qt::KeyboardModifiers mods)
+            :InputEvent(w, time, Touch, mods), devType(d), points(p), touchType(t) { }
         QTouchEvent::DeviceType devType;
         QList<QTouchEvent::TouchPoint> points;
         QEvent::Type touchType;
index d21d5d0..48a59ec 100644 (file)
@@ -47,6 +47,7 @@
 #include "qxcbconnection.h"
 #include "qxcbscreen.h"
 #include "qxcbdrag.h"
+#include "qxcbkeyboard.h"
 #include "qxcbwmsupport.h"
 
 #ifdef XCB_USE_DRI2
@@ -1256,7 +1257,7 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
     QPoint local(event->event_x, event->event_y);
     QPoint global(event->root_x, event->root_y);
 
-    Qt::KeyboardModifiers modifiers = Qt::NoModifier;
+    Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
 
     if (event->detail >= 4 && event->detail <= 7) {
         //logic borrowed from qapplication_x11.cpp
@@ -1266,30 +1267,32 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
                     || (event->detail == 6 || event->detail == 7));
 
         QWindowSystemInterface::handleWheelEvent(window(), event->time,
-                                                 local, global, delta, hor ? Qt::Horizontal : Qt::Vertical);
+                                                 local, global, delta, hor ? Qt::Horizontal : Qt::Vertical, modifiers);
         return;
     }
 
-    handleMouseEvent(event->detail, event->state, event->time, local, global);
+    handleMouseEvent(event->detail, event->state, event->time, local, global, modifiers);
 }
 
 void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *event)
 {
     QPoint local(event->event_x, event->event_y);
     QPoint global(event->root_x, event->root_y);
+    Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
 
-    handleMouseEvent(event->detail, event->state, event->time, local, global);
+    handleMouseEvent(event->detail, event->state, event->time, local, global, modifiers);
 }
 
 void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event)
 {
     QPoint local(event->event_x, event->event_y);
     QPoint global(event->root_x, event->root_y);
+    Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
 
-    handleMouseEvent(event->detail, event->state, event->time, local, global);
+    handleMouseEvent(event->detail, event->state, event->time, local, global, modifiers);
 }
 
-void QXcbWindow::handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global)
+void QXcbWindow::handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers)
 {
     connection()->setTime(time);
 
@@ -1298,7 +1301,7 @@ void QXcbWindow::handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_times
 
     buttons ^= button; // X event uses state *before*, Qt uses state *after*
 
-    QWindowSystemInterface::handleMouseEvent(window(), time, local, global, buttons);
+    QWindowSystemInterface::handleMouseEvent(window(), time, local, global, buttons, modifiers);
 }
 
 void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event)
index 8bed8a2..f470bbc 100644 (file)
@@ -104,7 +104,7 @@ public:
     void handleFocusInEvent(const xcb_focus_in_event_t *event);
     void handleFocusOutEvent(const xcb_focus_out_event_t *event);
 
-    void handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global);
+    void handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers);
 
     void updateSyncRequestCounter();
     void updateNetWmUserTime(xcb_timestamp_t timestamp);