Fix double click handling.
authorLaszlo Agocs <laszlo.p.agocs@nokia.com>
Tue, 6 Mar 2012 14:09:09 +0000 (16:09 +0200)
committerQt by Nokia <qt-info@nokia.com>
Tue, 6 Mar 2012 23:09:10 +0000 (00:09 +0100)
Until now double clicking in Qt 5 resulted in the following sequence of mouse
events: pressed, released, double clicked, released. This is wrong, the press
belonging to the second button down is missing. In Qt 4 that pressed event is
present.

The problem is not apparent in desktop environments because the double click is
functioning properly even when the second pressed is missing. However when
using a platform plug-in like wayland, where the clients receive only press,
move and release events, double click was broken because the second click was
effectively ignored (due to receiving nothing but a button release).

Change-Id: Ief6af12c666b23e544da4a68cb835cd577265469
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
src/gui/kernel/qguiapplication.cpp

index be82005..095336a 100644 (file)
@@ -933,6 +933,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
     QPointF globalPoint = e->globalPos;
 
     Qt::MouseButton button = Qt::NoButton;
+    bool doubleClick = false;
 
     if (QGuiApplicationPrivate::lastCursorPosition != globalPoint) {
         type = QEvent::MouseMove;
@@ -940,8 +941,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
         if (qAbs(globalPoint.x() - mousePressX) > mouse_double_click_distance||
             qAbs(globalPoint.y() - mousePressY) > mouse_double_click_distance)
             mousePressButton = Qt::NoButton;
-    }
-    else { // Check to see if a new button has been pressed/released.
+    } else { // Check to see if a new button has been pressed/released.
         for (int check = Qt::LeftButton;
             check <= int(Qt::MaxMouseButton);
              check = check << 1) {
@@ -956,25 +956,19 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
         }
         buttons = e->buttons;
         if (button & e->buttons) {
-            if ((e->timestamp - mousePressTime) < static_cast<ulong>(qApp->styleHints()->mouseDoubleClickInterval()) &&
-                    button == mousePressButton) {
-                type = QEvent::MouseButtonDblClick;
-                mousePressButton = Qt::NoButton;
-            }
-            else {
-                type = QEvent::MouseButtonPress;
-                mousePressTime = e->timestamp;
-                mousePressButton = button;
-                const QPoint point = QGuiApplicationPrivate::lastCursorPosition.toPoint();
-                mousePressX = point.x();
-                mousePressY = point.y();
-            }
-        }
-        else
+            ulong doubleClickInterval = static_cast<ulong>(qApp->styleHints()->mouseDoubleClickInterval());
+            doubleClick = e->timestamp - mousePressTime < doubleClickInterval && button == mousePressButton;
+            type = QEvent::MouseButtonPress;
+            mousePressTime = e->timestamp;
+            mousePressButton = button;
+            const QPoint point = QGuiApplicationPrivate::lastCursorPosition.toPoint();
+            mousePressX = point.x();
+            mousePressY = point.y();
+        } else {
             type = QEvent::MouseButtonRelease;
+        }
     }
 
-
     if (window) {
         QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers);
         ev.setTimestamp(e->timestamp);
@@ -1017,12 +1011,16 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
             fake.synthetic = true;
             processTouchEvent(&fake);
         }
+        if (doubleClick) {
+            mousePressButton = Qt::NoButton;
+            QMouseEvent dblClickEvent(QEvent::MouseButtonDblClick, localPoint, localPoint, globalPoint,
+                                      button, buttons, e->modifiers);
+            dblClickEvent.setTimestamp(e->timestamp);
+            QGuiApplication::sendSpontaneousEvent(window, &dblClickEvent);
+        }
     }
 }
 
-
-//### there's a lot of duplicated logic here -- refactoring required!
-
 void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent *e)
 {
     if (!e->window)
@@ -1041,8 +1039,6 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh
      }
 }
 
-
-
 // Remember, Qt convention is:  keyboard state is state *before*
 
 void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e)