From 495f4a600fbd13e19c3779910152d9f14af31ed0 Mon Sep 17 00:00:00 2001
From: David Faure <faure@kde.org>
Date: Wed, 28 Apr 2010 01:38:45 +0200
Subject: [PATCH] Add a QApplication::queryKeyboardModifiers() method.

This method returns the *current* keyboard modifiers, unlike
QApplication::keyboardModifiers which returns the keyboard modifiers
from the last keypress event in this process, as documented. However
in the case of drag-n-drop between processes we would not see the
pressed modifiers.
---
 src/gui/kernel/qapplication.cpp     |   21 ++++++++++++++++++++-
 src/gui/kernel/qapplication.h       |    1 +
 src/gui/kernel/qapplication_mac.mm  |    5 +++++
 src/gui/kernel/qapplication_qws.cpp |    5 +++++
 src/gui/kernel/qapplication_win.cpp |    5 +++++
 src/gui/kernel/qapplication_x11.cpp |   15 +++++++++++++++
 src/gui/kernel/qdnd_x11.cpp         |   17 +----------------
 7 files changed, 52 insertions(+), 17 deletions(-)

diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 43d5772..4db3d9c 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -3266,7 +3266,7 @@ bool QApplication::desktopSettingsAware()
     one of the above events. If no keys are being held Qt::NoModifier is
     returned.
 
-    \sa mouseButtons()
+    \sa mouseButtons(), queryKeyboardModifiers()
 */
 
 Qt::KeyboardModifiers QApplication::keyboardModifiers()
@@ -3275,6 +3275,25 @@ Qt::KeyboardModifiers QApplication::keyboardModifiers()
 }
 
 /*!
+    \fn Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
+
+    Queries and returns the state of the modifier keys on the keyboard.
+    Unlike keyboardModifiers, this method returns the actual keys held
+    on the input device at the time of calling the method.
+
+    It does not rely on the keypress events having been received by this
+    process, which makes it possible to check the modifiers while moving
+    a window, for instance. Note that in most cases, you should use
+    keyboardModifiers(), which is faster and more accurate since it contains
+    the state of the modifiers as they were when the currently processed
+    event was received.
+
+    \sa keyboardModifiers()
+
+    \since 4.8
+*/
+
+/*!
     Returns the current state of the buttons on the mouse. The current state is
     updated syncronously as the event queue is emptied of events that will
     spontaneously change the mouse state (QEvent::MouseButtonPress and
diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h
index 0242582..5c766e2 100644
--- a/src/gui/kernel/qapplication.h
+++ b/src/gui/kernel/qapplication.h
@@ -196,6 +196,7 @@ public:
     static void alert(QWidget *widget, int duration = 0);
 
     static Qt::KeyboardModifiers keyboardModifiers();
+    static Qt::KeyboardModifiers queryKeyboardModifiers();
     static Qt::MouseButtons mouseButtons();
 
     static void setDesktopSettingsAware(bool);
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index dd819e5..0d2e2a3 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -1422,6 +1422,11 @@ void QApplication::restoreOverrideCursor()
 }
 #endif // QT_NO_CURSOR
 
+Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
+{
+    return qt_mac_get_modifiers(GetCurrentEventKeyModifiers());
+}
+
 QWidget *QApplication::topLevelAt(const QPoint &p)
 {
 #ifndef QT_MAC_USE_COCOA
diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp
index 92eb304..04c55f4 100644
--- a/src/gui/kernel/qapplication_qws.cpp
+++ b/src/gui/kernel/qapplication_qws.cpp
@@ -2702,6 +2702,11 @@ void QApplication::alert(QWidget *, int)
 {
 }
 
+Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
+{
+    return keyboardModifiers(); // TODO proper implementation
+}
+
 int QApplication::qwsProcessEvent(QWSEvent* event)
 {
     Q_D(QApplication);
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index 78028eb..856a74b 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -1270,6 +1270,11 @@ Qt::KeyboardModifiers qt_win_getKeyboardModifiers()
     return modifiers;
 }
 
+Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
+{
+    return qt_win_getKeyboardModifiers();
+}
+
 /*****************************************************************************
   Routines to find a Qt widget from a screen position
  *****************************************************************************/
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index e7b7ed8..46a8ff7 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -3025,6 +3025,21 @@ void QApplicationPrivate::_q_alertTimeOut()
     }
 }
 
+Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
+{
+    Window root;
+    Window child;
+    int root_x, root_y, win_x, win_y;
+    uint keybstate;
+    for (int i = 0; i < ScreenCount(X11->display); ++i) {
+        if (XQueryPointer(X11->display, QX11Info::appRootWindow(i), &root, &child,
+                          &root_x, &root_y, &win_x, &win_y, &keybstate))
+            return X11->translateModifiers(keybstate & 0x00ff);
+    }
+    return 0;
+
+}
+
 /*****************************************************************************
   Special lookup functions for windows that have been reparented recently
  *****************************************************************************/
diff --git a/src/gui/kernel/qdnd_x11.cpp b/src/gui/kernel/qdnd_x11.cpp
index 92dd0a1..3b795be 100644
--- a/src/gui/kernel/qdnd_x11.cpp
+++ b/src/gui/kernel/qdnd_x11.cpp
@@ -1112,21 +1112,6 @@ void qt_xdnd_send_leave()
     waiting_for_status = false;
 }
 
-// TODO: remove and use QApplication::currentKeyboardModifiers() in Qt 4.8.
-static Qt::KeyboardModifiers currentKeyboardModifiers()
-{
-    Window root;
-    Window child;
-    int root_x, root_y, win_x, win_y;
-    uint keybstate;
-    for (int i = 0; i < ScreenCount(X11->display); ++i) {
-        if (XQueryPointer(X11->display, QX11Info::appRootWindow(i), &root, &child,
-                          &root_x, &root_y, &win_x, &win_y, &keybstate))
-            return X11->translateModifiers(keybstate & 0x00ff);
-    }
-    return 0;
-}
-
 void QX11Data::xdndHandleDrop(QWidget *, const XEvent * xe, bool passive)
 {
     DEBUG("xdndHandleDrop");
@@ -1175,7 +1160,7 @@ void QX11Data::xdndHandleDrop(QWidget *, const XEvent * xe, bool passive)
 
         // Drop coming from another app? Update keyboard modifiers.
         if (!qt_xdnd_dragging) {
-            QApplicationPrivate::modifier_buttons = currentKeyboardModifiers();
+            QApplicationPrivate::modifier_buttons = QApplication::queryKeyboardModifiers();
         }
 
         QDropEvent de(qt_xdnd_current_position, possible_actions, dropData,
-- 
1.7.2

