Drag And Drop files to external windows broken


#1

I'm actually trying to fix juce behaviour in linux for drag and drop, which works ok if used internally, but get broken as soon as you enable allowDragToExternalWindow.

First problem i get is that shouldDropFilesWhenDraggedExternally is called as soon as the temporary drag image window is created and the mouse is over it, that is because LinuxComponentPeer doesn't correctly handle windowIgnoreMouseClicks: following patch help in this.

diff --git a/Modules/juce_gui_basics/native/juce_linux_Windowing.cpp b/Modules/juce_gui_basics/native/juce_linux_Windowing.cpp
index c010776..50696bb 100644
--- a/Modules/juce_gui_basics/native/juce_linux_Windowing.cpp
+++ b/Modules/juce_gui_basics/native/juce_linux_Windowing.cpp
@@ -2956,7 +2956,7 @@ private:
         swa.background_pixmap = None;
         swa.colormap = colormap;
         swa.override_redirect = ((styleFlags & windowIsTemporary) != 0) ? True : False;
-        swa.event_mask = getAllEventsMask();
+        swa.event_mask = getAllEventsMask(styleFlags);
 
         windowH = XCreateWindow (display, parentToAddTo != 0 ? parentToAddTo : root,
                                  0, 0, 1, 1,
@@ -2964,9 +2964,12 @@ private:
                                  CWBorderPixel | CWColormap | CWBackPixmap | CWEventMask | CWOverrideRedirect,
                                  &swa);
 
+        unsigned int buttonMask = EnterWindowMask | LeaveWindowMask | PointerMotionMask;
+        if ((styleFlags & windowIgnoresMouseClicks) == 0)
+            buttonMask |= ButtonPressMask | ButtonReleaseMask;
+
         XGrabButton (display, AnyButton, AnyModifier, windowH, False,
-                     ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask,
-                     GrabModeAsync, GrabModeAsync, None, None);
+                     buttonMask, GrabModeAsync, GrabModeAsync, None, None);
 
         // Set the window context to identify the window handle object
         if (XSaveContext (display, (XID) windowH, windowHandleXContext, (XPointer) this))
@@ -3032,15 +3035,21 @@ private:
         XSync (display, false);
 
         XEvent event;
-        while (XCheckWindowEvent (display, windowH, getAllEventsMask(), &event) == True)
+        while (XCheckWindowEvent (display, windowH, getAllEventsMask(styleFlags), &event) == True)
         {}
     }
 
-    static int getAllEventsMask() noexcept
+    static int getAllEventsMask(int styleFlags) noexcept
     {
-        return NoEventMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask
-                 | EnterWindowMask | LeaveWindowMask | PointerMotionMask | KeymapStateMask
-                 | ExposureMask | StructureNotifyMask | FocusChangeMask;
+        int eventMask = NoEventMask
+                | KeyPressMask | KeyReleaseMask | KeymapStateMask
+                | EnterWindowMask | LeaveWindowMask | PointerMotionMask
+                | ExposureMask | StructureNotifyMask | FocusChangeMask;
+
+        if ((styleFlags & windowIgnoresMouseClicks) != 0)
+            eventMask |= ButtonPressMask | ButtonReleaseMask;
+
+        return eventMask;
     }
 
     template <typename EventType>

Now everything is good if i drag thing inside my juce window, but as soon as i drag exit my main window and go to another x11 window, the dragging image window desappear (even if the external drag to other windows works correctly) and the mouse pointer is changed to a dragging hand, no matter what i try to do.

I now see that linux performExternalDragDropOfFiles calls LinuxComponentPeer::externalDragInit which do some housekeeping and force the mouse pointer to be a dragging hand. Is there a away to have a more finer control on how this works ? Would like to continue use the juce dragImage even outside the juce window, and not want the component peer to change my mouse pointer forcibly.


#2

any chance to have my simple fix merged ?


#3

Didn't I do this a while ago..? May have just forgotten to say so on this thread.