From: Carlos Alberto Cortez Date: Mon, 29 Sep 2008 01:27:53 +0000 (-0000) Subject: 2008-09-28 Carlos Alberto Cortez X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=89f8ff09524057b091368e08f4951f5e231fc46a;p=mono.git 2008-09-28 Carlos Alberto Cortez * 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 --- diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog index 41143b3dc70..4794d5d17bf 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog @@ -1,3 +1,13 @@ +2008-09-28 Carlos Alberto Cortez + + * 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 * ThemeWin32Classic.cs: When drawing a status bar panel, don't diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Dnd.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Dnd.cs index 276b1428343..245242c3e31 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Dnd.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Dnd.cs @@ -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))