Index: /trunk/src/gui/kernel/qdnd_pm.cpp
===================================================================
--- /trunk/src/gui/kernel/qdnd_pm.cpp	(revision 450)
+++ /trunk/src/gui/kernel/qdnd_pm.cpp	(revision 451)
@@ -292,4 +292,53 @@
 }
 
+// Equivalent of QApplication::mouseButtons() (mouse events aren't delivered
+// to the window during DnD in PM so this metnod returns an incorrect value).
+static Qt::MouseButtons mouseButtons()
+{
+    Qt::MouseButtons buttons = Qt::NoButton;
+
+    if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000)
+        buttons |= Qt::LeftButton;
+    if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000)
+        buttons |= Qt::RightButton;
+    if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000)
+        buttons |= Qt::MidButton;
+
+    return buttons;
+}
+
+// Equivalent of QApplication::keyboardModifiers() (keyboard events aren't delivered
+// to the window during DnD in PM so this metnod returns an incorrect value).
+static Qt::KeyboardModifiers keyboardModifiers()
+{
+    Qt::KeyboardModifiers mods = Qt::NoModifier;
+
+    if (WinGetKeyState(HWND_DESKTOP, VK_SHIFT ) & 0x8000)
+        mods |= Qt::ShiftModifier;
+    if ((WinGetKeyState(HWND_DESKTOP, VK_ALT) & 0x8000) ||
+        (WinGetKeyState(HWND_DESKTOP, VK_ALTGRAF) & 0x8000))
+        mods |= Qt::AltModifier;
+    if (WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000)
+        mods |= Qt::ControlModifier;
+
+    // Note: we cannot properly detect LWIN/RWIN (Meta) key state here as it
+    // doesn't have a corresponding VK_ value. The best we can do is to check
+    // the physical keyboard state using the hardware scancode but it has the
+    // following problems:
+    //
+    //   1. The physical keyboard state may be out of sync with the current
+    //      input message we are processing.
+    //   2. The scancode may be hardware dependent
+    //
+    // 0x7E is what I get as a scancode value for LWIN from PM here.
+    // Unfortunately, I have no keyboard with RWIN around so I can't get its
+    // scan code.
+
+    if (WinGetPhysKeyState(HWND_DESKTOP, 0x7E) & 0x8000)
+        mods |= Qt::MetaModifier;
+
+    return mods;
+}
+
 void QDragManager::init_sys()
 {
@@ -448,6 +497,5 @@
                     QDragEnterEvent dee(pnt,
                                         toQDragDropActions(dragData->supportedOps),
-                                        data, QApplication::mouseButtons(),
-                                        QApplication::keyboardModifiers());
+                                        data, mouseButtons(), keyboardModifiers());
                     dee.setDropAction(dragData->lastAction);
                     sendDropEvent(dragOverWidget, &dee);
@@ -469,6 +517,5 @@
                     QDragMoveEvent dme(pnt,
                                        toQDragDropActions(dragData->supportedOps),
-                                       data, QApplication::mouseButtons(),
-                                       QApplication::keyboardModifiers());
+                                       data, mouseButtons(), keyboardModifiers());
                     // accept by default, since enter event was accepted.
                     dme.setDropAction(dragData->lastAction);
@@ -549,6 +596,6 @@
             dragData->setDropped(true);
 
-            QDropEvent de(pnt, dragData->lastAction, data, QApplication::mouseButtons(),
-                          QApplication::keyboardModifiers());
+            QDropEvent de(pnt, dragData->lastAction, data, mouseButtons(),
+                          keyboardModifiers());
             if (dragData->lastDropReply == DOR_DROP)
                 de.setDropAction(dragData->lastAction);
@@ -651,5 +698,5 @@
     // QPMObjectWindow interface
     MRESULT message(ULONG msg, MPARAM mp1, MPARAM mp2);
-    
+
 private:
     QList<DragWorker*> workers;
@@ -667,5 +714,5 @@
     bool gotExcl = false; // got isExclusive() worker?
     bool skipExcl = false; // skip isExclusive() or itemCount() > 1 workers?
-    ULONG coopLevel = 0; // itemCount() level for !isExclusive() workers 
+    ULONG coopLevel = 0; // itemCount() level for !isExclusive() workers
 
     bool gotExclForMime = false;
@@ -734,5 +781,5 @@
             // target's side (where the first encountered drop worker
             // for the given RMF would be used for actual data transfer
-            // anyway). See also QClipboard::setData(). 
+            // anyway). See also QClipboard::setData().
             break;
         }
@@ -755,5 +802,5 @@
 
     // remove either all exclusive workers or all their fall-back workers
-    // (depending on skipExcl) and remove duplicates 
+    // (depending on skipExcl) and remove duplicates
     for (QList<DragWorker*>::iterator it = workers.begin();
          it < workers.end();) {
@@ -767,9 +814,9 @@
     }
 
-#if defined(QDND_DEBUG)            
+#if defined(QDND_DEBUG)
     foreach (DragWorker *wrk, workers) {
         DEBUG(() << "QPMCoopDragWorker: Will use worker" << wrk
                  << "( isExclusive" << wrk->isExclusive()
-                 << "itemCount" << wrk->itemCount() << ")"); 
+                 << "itemCount" << wrk->itemCount() << ")");
     }
 #endif
@@ -785,10 +832,10 @@
     if (!firstWorker)
         return 0;
-    
+
     if (firstWorker->isExclusive() && firstWorker->itemCount() == 0) {
         // this is a super exclusive worker that will do everything on its own
         return firstWorker->hwnd();
     }
-    
+
     return QPMObjectWindow::hwnd();
 }
@@ -806,5 +853,5 @@
 {
     bool moveDisallowed = false;
-    
+
     foreach(DragWorker *wrk, workers) {
         // disallow the Move operation if at least one worker asked so
@@ -837,8 +884,8 @@
         return firstWorker->createDragInfo(targetName, supportedOps);
     }
-    
+
     // note that all workers at this place require the same amount of items
     // (guaranteed by collectWorkers())
-    
+
     DEBUG(() << "QPMCoopDragWorker: itemCnt" << itemCnt);
 
@@ -847,5 +894,5 @@
     if (!info)
         return 0;
-    
+
     // collect all mechanism/format pairs
     QByteArray allFormats;
@@ -866,5 +913,5 @@
 
     static ULONG itemID = 0;
-    
+
     const char *type = 0;
     const char *ext = 0;
@@ -885,5 +932,5 @@
         else
             name = QString(QLatin1String("%1 %2")).arg(targetName).arg(i + 1);
-        
+
         if (ext) {
             name += QLatin1Char('.');
@@ -896,10 +943,10 @@
         // Note 1: DRAGITEM::hstrType is actually ignored by WPS,
         // only the target extension matters.
-        
+
         // Note 2: We're not required to fill in the hwndItem field because we
         // use the DC_PREPARE flag (to indicate it will be filled later, after
         // DM_RENDERPREPARE); however, Mozilla refuses to render if hwndItem
         // is initially 0. Set it to our HWND instead (we'll issue a warning if
-        // DM_RENDER or DM_ENDCONVERSATION is erroneously sent to us) 
+        // DM_RENDER or DM_ENDCONVERSATION is erroneously sent to us)
 
         item->hwndItem = hwnd();
@@ -915,10 +962,10 @@
         item->fsSupportedOps = supportedOps;
     }
-   
+
     if (!ok) {
         DrgFreeDraginfo(info);
         info = 0;
     }
-    
+
     return info;
 }
@@ -930,5 +977,5 @@
             DEBUG(() << "Drop target sent DM_RENDERPREPARE after the DnD "
                         "session is over!");
-            // free the given DRAGTRANSFER structure to avoud memory leak 
+            // free the given DRAGTRANSFER structure to avoud memory leak
             DRAGTRANSFER *xfer = (DRAGTRANSFER *)mp1;
             if (xfer)
@@ -936,10 +983,10 @@
             return (MRESULT)FALSE;
         }
-    
+
         DRAGTRANSFER *xfer = (DRAGTRANSFER *)mp1;
         Q_ASSERT(xfer && xfer->pditem);
         if (!xfer || !xfer->pditem)
             return (MRESULT)FALSE;
-        
+
         // find the item's index (ordinal number)
         ULONG itemCnt = DrgQueryDragitemCount(info);
@@ -948,5 +995,5 @@
             if (DrgQueryDragitemPtr(info, index) == xfer->pditem)
                 break;
-        
+
         Q_ASSERT(index < itemCnt);
         if (index >= itemCnt)
@@ -956,5 +1003,5 @@
                  << QPMMime::queryHSTR(xfer->hstrSelectedRMF) << "for item"
                  << index << "( id" << xfer->pditem->ulItemID << ")");
-        
+
         QByteArray drm, drf;
         if (!QPMMime::parseRMF(xfer->hstrSelectedRMF, drm, drf)) {
@@ -976,10 +1023,10 @@
         return (MRESULT)(xfer->pditem->hwndItem ? TRUE : FALSE);
     }
-    
+
     if (msg == DM_RENDER || msg == DM_ENDCONVERSATION) {
         DEBUG(() << "Drop target sent DM_RENDER or DM_ENDCONVERSATION to the "
                     "drag source window instead of the drag item window!");
         if (msg == DM_RENDER) {
-            // free the given DRAGTRANSFER structure to avoud memory leak 
+            // free the given DRAGTRANSFER structure to avoud memory leak
             DRAGTRANSFER *xfer = (DRAGTRANSFER *)mp1;
             if (xfer)
@@ -987,5 +1034,5 @@
         }
     }
-    
+
     return (MRESULT)FALSE;
 }
@@ -1014,7 +1061,7 @@
         ULONG msg = WinQuerySysValue(HWND_DESKTOP, SV_BEGINDRAG) & 0xFFFF;
         switch(msg) {
-            case WM_BUTTON1MOTIONSTART: vkTerminate = VK_BUTTON1; break; 
-            case WM_BUTTON2MOTIONSTART: vkTerminate = VK_BUTTON2; break; 
-            case WM_BUTTON3MOTIONSTART: vkTerminate = VK_BUTTON3; break; 
+            case WM_BUTTON1MOTIONSTART: vkTerminate = VK_BUTTON1; break;
+            case WM_BUTTON2MOTIONSTART: vkTerminate = VK_BUTTON2; break;
+            case WM_BUTTON3MOTIONSTART: vkTerminate = VK_BUTTON3; break;
         }
 
@@ -1042,5 +1089,5 @@
 
     static QPMCoopDragWorker dragWorker;
-    
+
     bool ok = dragWorker.collectWorkers(o);
     Q_ASSERT(ok);
@@ -1098,5 +1145,5 @@
     bool moveDisallowed = dragWorker.cleanup(beingCancelled || target == 0);
     dragWorker.src = 0;
-    
+
     moveDisallowed |= beingCancelled || target == 0 ||
                       info->usOperation != DO_MOVE;
@@ -1139,5 +1186,5 @@
     if (!object || beingCancelled)
         return;
-    
+
     beingCancelled = true;
 
