diff --git a/modules/juce_gui_basics/native/juce_linux_X11.cpp b/modules/juce_gui_basics/native/juce_linux_X11.cpp
index a54ebede7..99fc0de5e 100644
--- a/modules/juce_gui_basics/native/juce_linux_X11.cpp
+++ b/modules/juce_gui_basics/native/juce_linux_X11.cpp
@@ -273,6 +273,7 @@ Atoms::Atoms (::Display* display)
     windowState                  = getIfExists (display, "_NET_WM_STATE");
 
     XdndAware                    = getCreating (display, "XdndAware");
+    XdndProxy                    = getCreating (display, "XdndProxy");
     XdndEnter                    = getCreating (display, "XdndEnter");
     XdndLeave                    = getCreating (display, "XdndLeave");
     XdndPosition                 = getCreating (display, "XdndPosition");
@@ -319,7 +320,7 @@ bool Atoms::isMimeTypeFile (::Display* display, const Atom atom)
 }
 
 
-const unsigned long Atoms::DndVersion = 3;
+const unsigned long Atoms::DndVersion = 5;
 
 //==============================================================================
 GetXProperty::GetXProperty (::Display* display, Window window, Atom atom,
diff --git a/modules/juce_gui_basics/native/juce_linux_X11.h b/modules/juce_gui_basics/native/juce_linux_X11.h
index f5c5cdd98..f79e6b318 100644
--- a/modules/juce_gui_basics/native/juce_linux_X11.h
+++ b/modules/juce_gui_basics/native/juce_linux_X11.h
@@ -106,7 +106,7 @@ struct Atoms
 
     AtomType protocols, protocolList[3], changeState, state, userTime,
              activeWin, pid, windowType, windowState,
-             XdndAware, XdndEnter, XdndLeave, XdndPosition, XdndStatus,
+             XdndAware, XdndProxy, XdndEnter, XdndLeave, XdndPosition, XdndStatus,
              XdndDrop, XdndFinished, XdndSelection, XdndTypeList, XdndActionList,
              XdndActionDescription, XdndActionCopy, XdndActionPrivate,
              XembedMsgType, XembedInfo,
diff --git a/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp b/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp
index ab9b9496b..777912176 100644
--- a/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp
+++ b/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp
@@ -1122,8 +1122,19 @@ public:
         return (void*) windowH;
     }
 
+    static Window getXdndProxy (Window window) noexcept
+    {
+        GetXProperty prop (display, window,
+                           Atoms::getIfExists (display, "XdndProxy"), 0, 1,
+                           false, XA_WINDOW);
+        return prop.success ? *reinterpret_cast<Window*> (prop.data) : None;
+    }
+
     static LinuxComponentPeer* getPeerFor (Window windowHandle) noexcept
     {
+        if (windowHandle == None)
+            return nullptr;
+
         XPointer peer = nullptr;
 
         if (display != nullptr)
@@ -1131,8 +1142,12 @@ public:
             ScopedXLock xlock (display);
 
             if (! XFindContext (display, (XID) windowHandle, windowHandleXContext, &peer))
+            {
                 if (peer != nullptr && ! ComponentPeer::isValidPeer (reinterpret_cast<LinuxComponentPeer*> (peer)))
                     peer = nullptr;
+            }
+            else
+                return getPeerFor (getXdndProxy (windowHandle));
         }
 
         return reinterpret_cast<LinuxComponentPeer*> (peer);
@@ -1343,6 +1358,22 @@ public:
         return false;
     }
 
+    Window getParent (Window child) const
+    {
+        Window* windowList = nullptr;
+        uint32 windowListSize = 0;
+        Window parent, root;
+
+        ScopedXLock xlock (display);
+        if (XQueryTree (display, child, &root, &parent, &windowList, &windowListSize) != 0)
+        {
+            if (windowList != nullptr)
+                XFree (windowList);
+        }
+
+        return parent;
+    }
+
     bool isParentWindowOf (Window possibleChild) const
     {
         if (windowH != 0 && possibleChild != 0)
@@ -2694,6 +2725,12 @@ private:
         xchangeProperty (windowH, atoms->XdndActionDescription, XA_STRING, 8, "", 0);
         xchangeProperty (windowH, atoms->XdndAware, XA_ATOM, 32, &atoms->DndVersion, 1);
 
+        if (parentWindow != None)
+        {
+            xchangeProperty (parentWindow, atoms->XdndProxy, XA_WINDOW, 32, (unsigned char *) &windowH, 1);
+            xchangeProperty (windowH, atoms->XdndProxy, XA_WINDOW, 32, (unsigned char *) &windowH, 1);
+        }
+
         initialisePointerMap();
         updateModifierMappings();
     }
@@ -2846,18 +2883,23 @@ private:
         dragState.reset (new DragState (display));
     }
 
-    void sendDragAndDropMessage (XClientMessageEvent& msg)
+    void sendDragAndDropMessage (Window handle, XClientMessageEvent& msg)
     {
         msg.type = ClientMessage;
         msg.display = display;
         msg.window = dragAndDropSourceWindow;
         msg.format = 32;
-        msg.data.l[0] = (long) windowH;
+        msg.data.l[0] = (long) handle;
 
         ScopedXLock xlock (display);
         XSendEvent (display, dragAndDropSourceWindow, False, 0, (XEvent*) &msg);
     }
 
+    void sendDragAndDropMessage (XClientMessageEvent& msg)
+    {
+        sendDragAndDropMessage (windowH, msg);
+    }
+
     bool sendExternalDragAndDropMessage (XClientMessageEvent& msg, Window targetWindow)
     {
         msg.type      = ClientMessage;
@@ -2928,6 +2970,7 @@ private:
         msg.data.l[4] = (long) dropAction;
 
         sendDragAndDropMessage (msg);
+        sendDragAndDropMessage (getParent (windowH), msg);
     }
 
     void sendExternalDragAndDropLeave (Window targetWindow)
