2008-09-28 Carlos Alberto Cortez <calberto.cortez@gmail.com>
authorCarlos Alberto Cortez <calberto.cortez@gmail.com>
Mon, 29 Sep 2008 01:27:53 +0000 (01:27 -0000)
committerCarlos Alberto Cortez <calberto.cortez@gmail.com>
Mon, 29 Sep 2008 01:27:53 +0000 (01:27 -0000)
* X11Dnd.cs: We have to send a dnd enter event as soon as we start the
operation, instead of waiting until we get any movement - this will
help us to have the data available in case no movement was detected
and _still_ we have to fire DragEnter and DragLeave/DragDrop events.
Finally add a windows.forms-only fallback to fire the mentioned events
if no movement at all was detected, just like .net does.
Fixes #381876.

svn path=/trunk/mcs/; revision=114347

mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Dnd.cs

index 41143b3dc7091b10a25beaf813f4fc8c01d2df3d..4794d5d17bf1a151b02f10846534e9640be13ec1 100644 (file)
@@ -1,3 +1,13 @@
+2008-09-28  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       * X11Dnd.cs: We have to send a dnd enter event as soon as we start the
+       operation, instead of waiting until we get any movement - this will
+       help us to have the data available in case no movement was detected
+       and _still_ we have to fire DragEnter and DragLeave/DragDrop events.
+       Finally add a windows.forms-only fallback to fire the mentioned events
+       if no movement at all was detected, just like .net does.
+       Fixes #381876.
+
 2008-09-27  Jonathan Pobst  <monkey@jpobst.com>
 
        * ThemeWin32Classic.cs: When drawing a status bar panel, don't
index 276b1428343d7b5977a5a84c598e210993a0aff0..245242c3e31ca13b5640a31de8025d749ade7cdb 100644 (file)
@@ -430,6 +430,10 @@ namespace System.Windows.Forms {
                        motion_poll = -1;
                        timer.Start ();
 
+                       // Send Enter to the window initializing the dnd operation - which initializes the data
+                       SendEnter (drag_data.Window, drag_data.Window, drag_data.SupportedTypes);
+                       drag_data.LastTopLevel = toplevel;
+
                        while (tracking && XplatUI.GetMessage (queue_id, ref msg, IntPtr.Zero, 0, 0)) {
 
                                if (msg.message >= Msg.WM_KEYFIRST && msg.message <= Msg.WM_KEYLAST) {
@@ -500,6 +504,25 @@ namespace System.Windows.Forms {
                                motion_poll++;
                }
 
+               // This routines helps us to have a DndEnter/DndLeave fallback when there wasn't any mouse movement
+               // as .Net does
+               private void DefaultEnterLeave (object user_data)
+               {
+                       Control source_control = Control.FromHandle (drag_data.Window);
+                       if (!source_control.AllowDrop)
+                               return;
+
+                       // `data' and other members are already available
+                       Point pos = Control.MousePosition;
+                       DragEventArgs drag_args = new DragEventArgs (data, 0, pos.X, pos.Y, drag_data.AllowedEffects, DragDropEffects.None);
+
+                       source_control.DndEnter (drag_args);
+                       if ((drag_args.Effect & drag_data.AllowedEffects) != 0)
+                               source_control.DndDrop (drag_args);
+                       else
+                               source_control.DndLeave (EventArgs.Empty);
+               }
+
                public void HandleButtonUpMsg ()
                {
                        if (drag_data.State == DragState.Beginning) {
@@ -514,6 +537,10 @@ namespace System.Windows.Forms {
 
                                        if (QueryContinue (false, DragAction.Cancel))
                                                return;
+
+                                       // fallback if no movement was detected, as .net does.
+                                       if (motion_poll == -1)
+                                               DefaultEnterLeave (drag_data.Data);
                                }
 
                                drag_data.State = DragState.None;
@@ -903,7 +930,6 @@ namespace System.Windows.Forms {
 
                private bool HandleStatusEvent (ref XEvent xevent)
                {
-                       
                        if (drag_data != null && drag_data.State == DragState.Entered) {
 
                                if (!QueryContinue (false, DragAction.Continue))